SyntaxHighlighter JS

2017-07-09

AWS terraform: Use DynamoDB locking

Please see the previous post on how to set up terraform to use a remote AWS S3 bucket to store the terraform.tfstate file (http://www.javajirawat.com/2017/07/aws-terraform-use-s3-remote-tfstate-file.html) . This example continues from the S3 bucket article.

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.

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

1 comment:

  1. 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