{"id":15733762,"url":"https://github.com/httpdss/terraform-aws-backend","last_synced_at":"2026-01-08T16:40:19.906Z","repository":{"id":66600270,"uuid":"303864911","full_name":"httpdss/terraform-aws-backend","owner":"httpdss","description":null,"archived":false,"fork":false,"pushed_at":"2020-10-14T00:57:32.000Z","size":49,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-02-06T08:28:42.058Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/httpdss.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-14T00:55:51.000Z","updated_at":"2020-10-14T21:40:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"efb780a5-7624-4fee-a4b3-803ee72af20a","html_url":"https://github.com/httpdss/terraform-aws-backend","commit_stats":{"total_commits":41,"total_committers":3,"mean_commits":"13.666666666666666","dds":"0.19512195121951215","last_synced_commit":"beb7ee0b229701f47c9853fb30529dbc568da0e5"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/httpdss%2Fterraform-aws-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/httpdss%2Fterraform-aws-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/httpdss%2Fterraform-aws-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/httpdss%2Fterraform-aws-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/httpdss","download_url":"https://codeload.github.com/httpdss/terraform-aws-backend/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246413242,"owners_count":20773053,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-04T01:00:40.917Z","updated_at":"2026-01-08T16:40:19.866Z","avatar_url":"https://github.com/httpdss.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# terraform-aws-backend\nA Terraform module which enables you to create and manage your [Terraform AWS Backend resources](https://www.terraform.io/docs/backends/types/s3.html), _with terraform_ to achieve a best practice setup.\n\nMore info on the aws (s3/dynamo) backend supported by this module is found here:\n\nhttps://www.terraform.io/docs/backends/types/s3.html\n\n\n# Bootstrapping your project\n\nThis terraform module helps you bootstrap any project which uses terraform for infrastructure management. [This module has a few options which are documented below. They allow you to change the behavior of this module.](#module-options)\n\n**_Why does this exist?_**\n\nOne of the most popular backend options for terraform is AWS (S3 for state, and DynamoDB for the lock table). If your project [specifies an AWS/S3 backend](https://www.terraform.io/docs/backends/types/s3.html), Terraform requires the existence of an S3 bucket in which to store _state_ information about your project, and a DynamoDB table to use for locking (this prevents you, your collaborators, and CI from stepping on each other with terraform commands which either modify your state or the infrastructure itself).\n\nThis terraform module creates/manages those resources:\n\n* Versioned S3 bucket for state\n* Properly configured DynamoDB lock table\n\n**If you follow this README carefully, you should be able to avoid the circular dependency which is inherent to the problem at hand.**\n\n**_What circular dependency?_**\n\nYour resulting terraform configuration block will refer to the resources created by this module. You wouldn't be able to `plan` or `apply` if your state bucket and lock table don't exist. The details which make this work can be seen under [the section which encourages you to postpone writing your terraform configuration block](#postpone-writing-your-terraform-configuration-block) and the [specific options used in the commands section below](#commands-are-the-fun-part).\n\n### a note on state bucket and s3 key naming\n\nFor the purposes of this intro, we'll use a bucket named `terraform-state-bucket`, but you'll want to choose an appropriate name for the s3 bucket in which terraform will store your infrastructure state. Perhaps something like `terraform-state-\u003cyour_project-name\u003e`, or, if you store all of your terraform state for all projects in a single bucket, `bucket-with-all-of-my-tf-states` along with a `key` that defines a path/key name which is more project specific such as `states/project-x-terraform.tfstate`.\n\n### postpone writing your terraform configuration block\n\nIn order to bootstrap your project with this module/setup, you will need to wait until **after** Step 4 (below) to write your [terraform configuration block](https://www.terraform.io/docs/configuration/terraform.html) into one of your `.tf` files. (Your \"terraform configuration block\" is the one that looks like this `terraform {}`.)\n\nIf you are updating an existing terraform-managed project, or you already wrote your `terraform {...}` block into one of your `.tf` files, you will run into the following error on Step 3 (`terraform plan`):\n\n![reinit required error](http://g.samstav.xyz/av5vyblbwq.png)\n\n\n### describe your terraform backend resources\n\n```hcl\nmodule \"backend\" {\n  source = \"github.com/samstav/terraform-aws-backend\"\n  backend_bucket = \"terraform-state-bucket\"\n  # using options, e.g. if you dont want a dynamodb lock table, uncomment this:\n  # dynamodb_lock_table_enabled = false\n}\n```\n\n### if using _existing_ backend resources (instead of creating new ones)\n\n#### re-using a DynamoDB lock table across multiple terraform-managed projects\n\nOne of the resources created and managed by this module is the DynamoDB Table for [terraform locking](https://www.terraform.io/docs/state/locking.html). This module provides a default name: `terraform-lock`. This table may actually be re-used across multiple different projects. In the case that you already have a DynamoDB table you would like to use for locking (or perhaps you are already using this module in another project), you can simply import that dynamodb table:\n\n```bash\n# If you are running Terraform at \u003e=0.12.*...\n$ terraform import module.backend.aws_dynamodb_table.tf_backend_state_lock_table terraform-lock\n\n# ...or if you are running it at \u003c0.12.*\n$ terraform import module.backend.aws_dynamodb_table.tf_backend_state_lock_table[0] terraform-lock\n```\n\n_(The `[0]` is needed in \u003c0.12.* because it is a \"conditional resource\" and you must refer to the 'count' index when importing, which is always `[0]`)_\n\nWhere `backend` is your chosen `terraform-aws-backend` module instance name, and `terraform-lock` is the DynamoDB table name you use for tf state locking.\n\nIf you attempt to apply this module without importing the existing DynamoDB table with the same name, you will run into the following error:\n\n```\nError: Error applying plan:\n\n1 error(s) occurred:\n\n* module.backend.aws_dynamodb_table.tf_backend_state_lock_table: 1 error(s) occurred:\n\n* aws_dynamodb_table.tf_backend_state_lock_table: ResourceInUseException: Table already exists: terraform-lock\n\tstatus code: 400, request id: F35KO0U78JJOIWEJFNJNJHSLDBFF66Q9ASUAAJG\n ```\n\n### commands are the fun part\n\nThe following commands will get you up and running:\n```bash\n# Step 1: Download modules\nterraform get -update\n# Step 2: Initialize your directory/project for use with terraform\n# The use of -backend=false here is important: it avoids backend configuration\n# on our first call to init since we havent created our backend resources yet\nterraform init -backend=false\n# Step 3: Create infrastructure plan for just the tf backend resources\n# Target only the resources needed for our aws backend for terraform state/locking\nterraform plan -out=backend.plan -target=module.backend\n# Step 4: Apply the infrastructure plan\nterraform apply backend.plan\n# Step 5: Only after applying (building) the backend resources, write our terraform config.\n# Now we can write the terraform backend configuration into our project\n# Instead of this command, you can write the terraform config block into any of your .tf files\n# Please see \"writing your terraform configuration\" below for more info\necho 'terraform { backend \"s3\" {} }' \u003e conf.tf\n# Step 6: Reinitialize terraform to use your newly provisioned backend\nterraform init -reconfigure \\\n    -backend-config=\"bucket=terraform-state-bucket\" \\\n    -backend-config=\"key=states/terraform.tfstate\" \\\n    -backend-config=\"encrypt=1\" \\\n    # leave this next line out if you dont want to use a tf lock\n    -backend-config=\"dynamodb_table=terraform-lock\"\n```\n\n### writing your terraform configuration\n\nhttps://www.terraform.io/docs/configuration/terraform.html\n\nInstead of using the `echo` command above in Step 5 (provided only for proof of concept), you can just write your terraform config into one of your \\*.tf files. Otherwise you'll end up needing to provide the `-backend-config` [parameters partial configuration](https://www.terraform.io/docs/backends/config.html#partial-configuration) every single time you run `terraform init` (which might be often).\n\n```hcl\nterraform {\n  backend \"s3\" {\n    bucket = \"terraform-state-bucket\"\n    key = \"states/terraform.tfstate\"\n    dynamodb_table = \"terraform-lock\"\n    encrypt = \"true\"\n  }\n}\n```\n\n### reconfiguring terraform after building your backend resources\n\nTerraform might ask you if you want to copy your existing state. You probably do:\n\n![yes](http://g.samstav.xyz/bgs7hwsiqa.png)\n\n## Module options\n\nOptions and configuration for this module are exposed via terraform variables.\n\n\n#### `backend_bucket`\n\nThis is the only variable which has no default but is required. You will need to define this value in your terraform-aws-backend module block. There are a few ways to do this, here's a couple:\n\n```hcl\nmodule \"backend\" {\n  source = \"github.com/samstav/terraform-aws-backend\"\n  backend_bucket = \"terraform-state-bucket\"\n}\n```\n\nOR\n\n```hcl\nvariable \"backend_bucket\" {\n  default = \"terraform-state-bucket\"\n}\n\nmodule \"backend\" {\n  source = \"github.com/samstav/terraform-aws-backend\"\n  backend_bucket = \"${var.backend_bucket}\"\n}\n```\n\n#### `dynamodb_lock_table_enabled`\n\n_Defaults to `true`._\n\n- Set to false or 0 to prevent this module from creating the DynamoDB table to use for terraform state locking and consistency. More info on locking for aws/s3 backends: https://www.terraform.io/docs/backends/types/s3.html. More information about how terraform handles booleans here: https://www.terraform.io/docs/configuration/variables.html\"\n}\n\n#### `dynamodb_lock_table_stream_enabled`\n\n_Defaults to `false`._\n\nAffects terraform-aws-backend module behavior. Set to false or 0 to disable DynamoDB Streams for the table. More info on DynamoDB streams: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html. More information about how terraform handles booleans here: https://www.terraform.io/docs/configuration/variables.html\n\n\n#### `dynamodb_lock_table_stream_view_type`\n\n_Defaults to `NEW_AND_OLD_IMAGES`_\n\nOnly applies if `dynamodb_lock_table_stream_enabled` is true.\n\n#### `dynamodb_lock_table_name`\n\n_Defaults to `terraform-lock`_\n\nThe name of your [terraform state locking](https://www.terraform.io/docs/state/locking.html) DynamoDB Table.\n\n#### `lock_table_read_capacity`\n\n_Defaults to `1` Read Capacity Unit._\n\nMore on DynamoDB Capacity Units: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/CapacityUnitCalculations.html\n\n\n#### `lock_table_write_capacity`\n_Defaults to `1` Write Capacity Unit._\n\nMore on DynamoDB Capacity Units: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/CapacityUnitCalculations.html\n\n#### `kms_key_id`\n_Defaults to ``._\n\nEncryption key to use for encrypting the terraform remote state s3 bucket. If not specified, then AWS-S3 encryption key management method will be used, which uses keys derived from the account master kms key. If specified, then AWS-KMS encryption key management method will be used. If the kms_key_id is specified, then you must specify the backend config option `kms_key_id`. More on s3 bucket server side encryption: https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html and https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html\n\n### terraform-aws-backend terraform variables\n\nSee variables available for module configuration\n\nhttps://github.com/samstav/terraform-aws-backend/blob/master/variables.tf\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhttpdss%2Fterraform-aws-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhttpdss%2Fterraform-aws-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhttpdss%2Fterraform-aws-backend/lists"}