****https://zerotomastery.io/cheatsheets/terraform-cheat-sheet/
https://zerotomastery.io/cheatsheets/terraform-cheat-sheet/#declaring-variables
cheat-sheet/
1.declare variable types string/number/bool/map/tuple
2.use state backend and
3.use data source
4.use loops
count meta-argument: loop over resources.
for_each meta-argument: loop over resources and inline blocks within a resource.
for expressions: loop over lists and maps.
5.Use splat expression
Splat Expressions
A splat expression provides a more concise way to express a common operation that could otherwise be performed with a for expression.
# Launch an EC2 instance
resource "aws_instance" "server" {
ami = "ami-05cafdf7c9f772ad2"
instance_type = "t2.micro"
count = 3
}
output "private_addresses"{
value = aws_instance.server[*].private_ip # splat expression
}
6.Use dynamic blocks
7.use Conditional Expressions
8.Use Terraform Locals
9.Buildin function like
max(5, 12, 9)
min(12, 54, 3)
join(", ", ["foo", "bar", "baz"])
split(",", "foo,bar,baz")
replace("hello world", "/w.*d/", "everybody")
substr("hello world", 1, 4)
element(very importnat must use
lookup very importnat must use
timestamp()
cidrhost("10.1.2.240/28", 1)
Troubleshooting and Logging
export TF_LOG_PATH=terraform.log
10. use the File, local-exec, remote-exec.
terraform apply -auto-approve -var-file=web-prod.tfvars
provider "aws" {
region = "us-west-2" # Specify your desired region
}
# Define a VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main-vpc"
}
}
# Define subnets
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-west-2a"
tags = {
Name = "public-subnet"
}
}
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-west-2b"
tags = {
Name = "private-subnet"
}
}
# Define an internet gateway
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-igw"
}
}
# Define a route table
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "public-route-table"
}
}
# Associate route table with the public subnet
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
# Define security groups
resource "aws_security_group" "allow_ssh" {
vpc_id = aws_vpc.main.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_ssh"
}
}
resource "aws_security_group" "allow_http" {
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_http"
}
}
# Define an S3 bucket
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-unique-bucket-name-12345"
tags = {
Name = "my_bucket"
}
}
# Define an IAM role for Lambda
resource "aws_iam_role" "lambda_exec_role" {
name = "lambda_exec_role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Sid = ""
Principal = {
Service = "lambda.amazonaws.com"
}
},
]
})
tags = {
Name = "lambda_exec_role"
}
}
resource "aws_iam_role_policy" "lambda_policy" {
name = "lambda_policy"
role = aws_iam_role.lambda_exec_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Effect = "Allow"
Resource = "arn:aws:logs:*:*:*"
},
{
Action = "s3:*"
Effect = "Allow"
Resource = "*"
},
]
})
}
# Define a Lambda function
resource "aws_lambda_function" "my_lambda" {
function_name = "my_lambda_function"
role = aws_iam_role.lambda_exec_role.arn
handler = "index.handler"
runtime = "nodejs14.x"
# Replace the following with the path to your deployment package
filename = "path/to/your/lambda/package.zip"
source_code_hash = filebase64sha256("path/to/your/lambda/package.zip")
environment {
variables = {
BUCKET = aws_s3_bucket.my_bucket.bucket
}
}
}
# Define a Launch Template
resource "aws_launch_template" "web_server" {
name_prefix = "web-server-"
image_id = "ami-0c55b159cbfafe1f0" # Specify the AMI ID
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.allow_ssh.id, aws_security_group.allow_http.id]
tag_specifications {
resource_type = "instance"
tags = {
Name = "web-server"
}
}
}
# Define an Auto Scaling Group
resource "aws_autoscaling_group" "web_asg" {
desired_capacity = 2
max_size = 3
min_size = 1
launch_template {
id = aws_launch_template.web_server.id
version = "$Latest"
}
vpc_zone_identifier = [aws_subnet.public.id]
tags = [
{
key = "Name"
value = "web-server-asg"
propagate_at_launch = true
}
]
}
# Define a Load Balancer
resource "aws_lb" "web_lb" {
name = "web-lb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.allow_http.id]
subnets = [aws_subnet.public.id]
tags = {
Name = "web-lb"
}
}
resource "aws_lb_target_group" "web_tg" {
name = "web-tg"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
target_type = "instance"
health_check {
path = "/"
interval = 30
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 2
matcher = "200"
}
tags = {
Name = "web-tg"
}
}
resource "aws_lb_listener" "web_listener" {
load_balancer_arn = aws_lb.web_lb.arn
port = 80
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.web_tg.arn
}
tags = {
Name = "web-listener"
}
}
resource "aws_autoscaling_attachment" "asg_attachment" {
autoscaling_group_name = aws_autoscaling_group.web_asg.name
lb_target_group_arn = aws_lb_target_group.web_tg.arn
}
================================================
# Declare Variables
variable "region" {
description = "The AWS region to deploy to"
type = string
default = "us-west-2"
}
variable "instance_count" {
description = "Number of instances to launch"
type = number
default = 3
}
variable "instance_type" {
description = "The type of instance to launch"
type = string
default = "t2.micro"
}
variable "environment" {
description = "The environment for the resources"
type = string
default = "production"
}
variable "tags" {
description = "A map of tags to assign to the resources"
type = map(string)
default = {
Project = "TerraformDemo"
Owner = "DevOpsTeam"
}
}
# State Backend
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "global/s3/terraform.tfstate"
region = var.region
encrypt = true
dynamodb_table = "terraform-locks"
}
}
# Data Source
data "aws_ami" "latest_amazon_linux" {
most_recent = true
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["amazon"]
}
# Resources with Loops and Expressions
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = merge(var.tags, {
Name = "main-vpc"
})
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = element(["us-west-2a", "us-west-2b"], count.index)
tags = merge(var.tags, {
Name = "public-subnet-${count.index}"
})
}
resource "aws_security_group" "allow_ssh_http" {
vpc_id = aws_vpc.main.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = merge(var.tags, {
Name = "allow_ssh_http"
})
}
resource "aws_instance" "server" {
ami = data.aws_ami.latest_amazon_linux.id
instance_type = var.instance_type
count = var.instance_count
subnet_id = element(aws_subnet.public[*].id, count.index % length(aws_subnet.public[*].id))
vpc_security_group_ids = [aws_security_group.allow_ssh_http.id]
tags = merge(var.tags, {
Name = "web-server-${count.index}"
})
}
output "private_addresses" {
value = aws_instance.server[*].private_ip
}
# Dynamic Blocks
resource "aws_autoscaling_group" "web_asg" {
launch_template {
id = aws_launch_template.web_server.id
version = "$Latest"
}
vpc_zone_identifier = aws_subnet.public[*].id
min_size = 1
max_size = 3
desired_capacity = var.instance_count
tag {
key = "Name"
value = "web-server-asg"
propagate_at_launch = true
}
dynamic "tag" {
for_each = var.tags
content {
key = tag.key
value = tag.value
propagate_at_launch = true
}
}
}
# Conditional Expressions
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-unique-bucket-name-12345"
tags = merge(var.tags, {
Environment = var.environment == "production" ? "prod" : "dev"
})
}
# Terraform Locals
locals {
bucket_name = "my-unique-bucket-${var.environment}"
instance_tags = merge(var.tags, {
Environment = var.environment
})
}
resource "aws_s3_bucket" "my_bucket_local" {
bucket = local.bucket_name
tags = local.instance_tags
}
# Built-in Functions
output "max_value" {
value = max(5, 12, 9)
}
output "min_value" {
value = min(12, 54, 3)
}
output "joined_string" {
value = join(", ", ["foo", "bar", "baz"])
}
output "split_string" {
value = split(",", "foo,bar,baz")
}
output "replaced_string" {
value = replace("hello world", "/w.*d/", "everybody")
}
output "substring" {
value = substr("hello world", 1, 4)
}
output "element_example" {
value = element(["a", "b", "c"], 1)
}
output "lookup_example" {
value = lookup(var.tags, "Owner", "Unknown")
}
output "timestamp_example" {
value = timestamp()
}
output "cidrhost_example" {
value = cidrhost("10.1.2.240/28", 1)
}
# Provisioners: File, local-exec, remote-exec
resource "null_resource" "example" {
provisioner "local-exec" {
command = "echo 'Hello, World!'"
}
provisioner "file" {
content = "This is a test file."
destination = "/tmp/test.txt"
}
provisioner "remote-exec" {
inline = [
"echo 'Hello, World!' > /tmp/remote_test.txt"
]
connection {
type = "ssh"
user = "ec2-user"
private_key = file("~/.ssh/id_rsa")
host = aws_instance.server[0].public_ip
}
}
}
# Usage Instructions
# 1. Install Terraform: Ensure Terraform is installed on your local machine.
# 2. Initialize Terraform: Navigate to your project directory and run `terraform init` to initialize Terraform.
# 3. Validate the Configuration: Use `terraform validate` to check the configuration for syntax errors.
# 4. Apply the Configuration: Run `terraform apply -auto-approve -var-file=web-prod.tfvars` to create the resources.
# Troubleshooting and Logging
# export TF_LOG=DEBUG
# export TF_LOG_PATH=terraform.log
0 Comments