Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to configure remote backend for environments #3

Open
deltakroneker opened this issue Mar 11, 2022 · 1 comment
Open

How to configure remote backend for environments #3

deltakroneker opened this issue Mar 11, 2022 · 1 comment

Comments

@deltakroneker
Copy link

I have successfully added backend.tf file with all resources and authorizations that allow my IAM user (from the profile) used by TF to be able to write/read to S3 and DynamoDB and use the remote backend for storing the state of the main root module.

Now, I'm looking to expand and start creating resources in the environment root module, and immediately there's a question:

Where do the state files of each workspace within environments (dev,stage,prod) live?
Should they be part of the main account (subdirectories inside project-name-main-backend S3 Bucket), or should they be in the same structure but in their own accounts (project-name-INSERT_ENV_HERE-backend S3 buckets).

Any thoughts on the matter?

Here's my main/backend.tf for reference:

terraform {
  backend "s3" {
    bucket         = "project-name-main-backend"
    region         = "us-east-1"
    key            = "terraform.tfstate"
    dynamodb_table = "project-name-main-backend"
    profile        = "project-name_admin"
  }
}

# S3 Bucket

resource "aws_s3_bucket" "backend" {
  bucket = "project-name-main-backend"
  lifecycle {
    prevent_destroy = true
  }
}

resource "aws_s3_bucket_versioning" "backend" {
  bucket = aws_s3_bucket.backend.id
  versioning_configuration {
    status = "Enabled"
  }
  lifecycle {
    prevent_destroy = true
  }
}

resource "aws_s3_bucket_ownership_controls" "backend" {
  bucket = aws_s3_bucket.backend.id
  rule {
    object_ownership = "BucketOwnerEnforced"
  }
  lifecycle {
    prevent_destroy = true
  }
}

resource "aws_s3_bucket_public_access_block" "backend" {
  bucket                  = aws_s3_bucket.backend.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
  lifecycle {
    prevent_destroy = true
  }
}

# DynamoDB

resource "aws_dynamodb_table" "backend" {
  name           = "project-name-main-backend"
  read_capacity  = 5
  write_capacity = 5
  hash_key       = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
  lifecycle {
    prevent_destroy = true
  }
}

# Access policies

resource "aws_iam_policy" "backend_s3" {
  name   = "TerraformBackendS3Policy"
  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::mybucket"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
      "Resource": "${aws_s3_bucket.backend.arn}/${terraform.workspace}/terraform.tfstate"
    }
  ]
}
EOF
  lifecycle {
    prevent_destroy = true
  }
}

resource "aws_iam_policy" "backend_dynamodb" {
  name   = "TerraformBackendDynamoDBPolicy"
  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:DeleteItem"
      ],
      "Resource": "${aws_dynamodb_table.backend.arn}"
    }
  ]
}
EOF
  lifecycle {
    prevent_destroy = true
  }
}

# Access policies attachments

data "aws_iam_user" "admin" {
  user_name = "admin"
}

resource "aws_iam_user_policy_attachment" "admin_terraform_s3" {
  user       = data.aws_iam_user.admin.user_name
  policy_arn = aws_iam_policy.backend_s3.arn
  lifecycle {
    prevent_destroy = true
  }
}

resource "aws_iam_user_policy_attachment" "admin_terraform_dynamodb" {
  user       = data.aws_iam_user.admin.user_name
  policy_arn = aws_iam_policy.backend_dynamodb.arn
  lifecycle {
    prevent_destroy = true
  }
}
@cobusbernard
Copy link
Owner

Apologies for the slow response. When using workspaces, it uses the same backend configuration, but with an additional folder name layer to keep the state files between workspaces separate. I added tutorials that cover both the initial bootstrapping, and then how to expand it to use multiple accounts with workspaces - see the updated readme, I've added links in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants