In this challenge I need to create a S3 bucket and a DynamoDB for remote state and lock backend setup for Terraform. As resources an EC2 Instance will be created.
Services Covered
Terraform
Lab description
In this challenge I need to create a S3 bucket and a DynamoDB for remote state and lock backend setup for Terraform. As resources an EC2 Instance will be created.
Project structure
├── main.tf
├── terraform.tfvars
└── variables.tf
Learning Objectives
- Create Terraform template to launch resources
- Create EC2 instance
- Create remote backend on S3 and lock featuring DynamoDB
- Use variables in the template
Lab date
18-11-2021
Prerequisites
- AWS account
- Terraform installed
Lab steps
- Set up the S3 remote state backend by creating a S3 bucket and DynamoDB table. Create unique bucket name by running:
S3NAME="terraformstate$(date | md5sum | head -c 8)"
THen create bucket:
aws s3api create-bucket --bucket $S3NAME --region us-west-2 --create-bucket-configuration LocationConstraint=us-west-2
Add encryption:
aws s3api put-bucket-encryption --bucket $S3NAME --server-side-encryption-configuration={"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}
Enable versioning:
aws s3api put-bucket-versioning --bucket $S3NAME --versioning-configuration Status=Enabled
Create table:
aws dynamodb create-table --table-name terraform-state-lock --attribute-definitions AttributeName=LockID,AttributeType=S --key-schema AttributeName=LockID,KeyType=HASH --region us-west-2 --provisioned-throughput ReadCapacityUnits=20,WriteCapacityUnits=20
Set environment variable for table:
TABLE=$(aws dynamodb list-tables --region us-west-2 --query "TableNames[]" --output text)
Check the environment variables values:
echo "Use Bucket: $S3NAME and Table: $TABLE"
- Create main.tf and variables.tf. In main.tf use the following code:
terraform { required_providers { aws = { source = "hashicorp/aws" version = "3.7" } } backend "s3" { bucket = "<<REPLACE_ME_$S3NAME>>" key = "<<PATH_TO>>/terraform.tfstate" region = "us-west-2" dynamodb_table = "$TABLE" encrypt = true } } provider "aws" { region = "us-west-2" } resource "aws_instance" "cloudacademylabs" { ami = var.amis[var.region] instance_type = var.instance_type tags = { Name = "cloudacademylabs" } }
Variables.tf:
variable "bucket" { type = string } variable "amis" { type = map(any) default = { "us-west-2": "ami-00be885d550dcee43" } } variable "instance_type" { type = string } variable "region" { type = string }
And then in terraform.tfvars you’ll specify the requirements for region, instance_type.
- Apply the set-up:
terraform init terraform apply