zudell.io.

< Back

jon@zudell.io > aws_tf_bootstrap v1.0.0

# Posted1729209600000

Bootstrapping Terraform to manage your AWS environment can be a huge pain. The issue is terraform will not be able to create the the bucket or dynamodb table to store the state. This is a chicken and egg problem. Here's a brief guide on to set it up.


# Software Dependancies

You will need to have the following software installed:


# Overview

In order for terraform to store its state in AWS it needs to configure the required provider like so.


main.tf
1terraform {
2  required_providers {
3    aws = {
4      source  = "hashicorp/aws"
5      version = "~> 5.0"
6    }
7  }
8  backend "s3" {
9    encrypt = true
10    bucket = "terraform-state-infrastructure"
11    key    = "terraform.tfstate"
12    region = "us-east-1"
13    dynamodb_table = "terraform-dynamodb-locks"
14  }
15}

The issue is terraform will not be able to create the the bucket or dynamodb table to store the state. This is a chicken and egg problem.


# Resource Creation

We don't like getting our hands dirty with the AWS cli and we will not sully ourselves by touching the web console. We will use terraform like god intended. The solution is to create the bucket, associated policies, and dynamodb table using terraform with no backend. To do so run terraform apply. This will create the resources in AWS.


main.tf
1terraform {
2  required_providers {
3    aws = {
4      source  = "hashicorp/aws"
5      version = "~> 5.0"
6    }
7    # backend "s3" {
8    #   encrypt = true
9    #   bucket = "terraform-state-infrastructure"
10    #   key    = "terraform.tfstate"
11    #   region = "us-east-1"
12    #   dynamodb_table = "terraform-dynamodb-locks"
13    # }
14  }
15}
16
17variable "terraform_iam_role" {
18  description = "The IAM role to assume when running terraform"
19  type        = string
20}
21
22resource "aws_s3_bucket" "terraform_state_bucket" {
23  bucket = "terraform-state-infrastructure"
24}
25
26resource "aws_s3_bucket_policy" "terraform_state_policy" {
27  bucket = aws_s3_bucket.terraform_state_bucket.id
28
29  policy = jsonencode({
30    Version = "2012-10-17"
31    Statement = [
32      {
33        Effect = "Allow"
34        Principal = {
35          AWS = "${var.terraform_iam_role}"
36        }
37        Action = [
38          "s3:GetObject",
39          "s3:PutObject",
40          "s3:DeleteObject",
41          "s3:ListBucket"
42        ]
43        Resource = [
44          "${aws_s3_bucket.terraform_state_bucket.arn}",
45          "${aws_s3_bucket.terraform_state_bucket.arn}/*"
46        ]
47      }
48    ]
49  })
50}
51
52resource "aws_dynamodb_table" "terraform_dynamodb_locks" {
53  name         = "terraform-locks"
54  billing_mode = "PAY_PER_REQUEST"
55  hash_key     = "LockID"
56
57  attribute {
58    name = "LockID"
59    type = "S"
60  }
61}

# Bootstrapping

Afterward executing the terraform apply delete the .terraform directory and the terraform .tfstate files then uncomment the backend. Doing this will create the bucket, associated IAM role and dynamodb table. Finally uncomment the backend and run terraform init -migrate-state. Congratulations, you have fulfilled the capitalist dream of pulling yourself up by your own bootstraps.

< Back