Remote terraform state file allows multiple terraform servers to manage the same resources. However if two people try to modify the same terraform state at the same time, it may lead to corruption and errors. Terraform can be configured to use AWS DynamoDB to lock the state file and prevent concurrent edits.
AWS Dynamo DB is a cloud NoSQL key-value database.
Setup:
Create an AWS DynamoDB with terraform to lock the terraform.tfstate.
1.) Create terraform main.tf for AWS DynamoDB
See https://github.com/juttayaya/devops/blob/master/hashicorp/terraform/s3-tfstate-example/dynamodb/main.tf
See https://github.com/juttayaya/devops/blob/master/hashicorp/terraform/s3-tfstate-example/dynamodb/main.tf
provider "aws" { region = "us-east-1" } resource "aws_dynamodb_table" "dynamodb-terraform-lock-example" { name = "terraform-lock-example" hash_key = "LockID" read_capacity = 5 write_capacity = 5 attribute { name = "LockID" type = "S" } tags { Name = "Terraform Lock Table Example" Org = "JavaJirawat" } }
You can name the DynamoDB table to anything you wish. The hash_key must be a String attribute named LockID
2.) Execute main.tf to create the DynamoDB table on AWS
Run the command
terraform apply
The AWS account that executes terraform needs AmazonDynamoDBFullAccess permission in the region you are creating the database table
https://console.aws.amazon.com/iam/home?region=us-east-1#/policies/arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess
Usage:
Here is an example of using the DynamoDB table we just created to lock a terraform.tfstate for a AWS EC2 resource.
1.) Create terraform main.tf for AWS EC2 server with a S3 backend to store the terraform.tfstate file and a DynamoDB table to lock it.
terraform { backend "s3" { bucket = "terraform-s3-tfstate-example" region = "us-east-1" key = "example/ec2-with-locking/terraform.tfstate" dynamodb_table = "terraform-lock-example" encrypt = true } } provider "aws" { region = "us-east-1" } # Amazon Linux AMI resource "aws_instance" "ec2-with-locking-example" { count = 1 ami = "ami-a4c7edb2" instance_type = "t2.micro" lifecycle { create_before_destroy = true } tags { Name = "Example for DynamoDB lock" Org = "JavaJirawat" } }
The dynamodb_table value must match the name of the DynamoDB table we created.
2.) Initialize the terraform S3 backend
Run the command
terraform init
Type in "yes" for any prompt.
3.) Execute main.tf to create the EC2 server on AWS
Run the command
terraform apply
The AWS account that executes terraform needs AmazonEC2FullAccess permission in the region you are creating the EC2 server
https://console.aws.amazon.com/iam/home?region=us-east-1#/policies/arn:aws:iam::aws:policy/AmazonEC2FullAccess
Is there any reason you do not suggest having the aws_dynamodb_table and aws_s3_bucket resources in the same main.tf? The way it's laid out here, I end up with 3 main.tf's.
ReplyDelete