From 444a38ff1a4b957108863b6e254b2f6f9ae8fbef Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Thu, 22 Jul 2021 14:35:33 -0700 Subject: [PATCH] website: DynamoDB now supports fine-grain IAM policies Our S3 backend documentation previously asserted that DynamoDB doesn't support precise enough IAM policies to write per-environment access policies for S3 backend locking. In the meantime the DynamoDB team added new capabilities for matching with various DynamoDB-specific condition keys, so we can now show an example of an environment-specific locking permission and also link to the relevant DynamoDB documentation for more details. While working on this I noticed that this "Multi-account AWS Architecture" section would probably more at home on HashiCorp Learn in our modern documentation architecture, since it's much more like a tutorial than the typical content on these pages, but for the moment I've just updated it in-place and we can consider relocating it to Learn, or writing some new content covering similar ground there, in a separate change later. --- .../docs/language/settings/backends/s3.mdx | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/website/docs/language/settings/backends/s3.mdx b/website/docs/language/settings/backends/s3.mdx index d0d2490248..e56f4cd1ab 100644 --- a/website/docs/language/settings/backends/s3.mdx +++ b/website/docs/language/settings/backends/s3.mdx @@ -523,8 +523,7 @@ to only a single state object within an S3 bucket is shown below: } ``` -The example backend configuration below documents the corresponding `bucket` -and `key` arguments: +The example backend configuration below documents the corresponding `bucket` and `key` arguments: ```hcl terraform { @@ -538,40 +537,37 @@ terraform { Refer to the [AWS documentation on S3 access control](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) for more details. -It is also possible to apply fine-grained access control to the DynamoDB -table used for locking. When Terraform puts the state lock in place during `terraform plan`, it stores the full state file as a document and sets the s3 object key as the partition key for the document. After the state lock is released, Terraform places a digest of the updated state file in DynamoDB. The key is similar to the one for the original state file, but is suffixed with `-md5`. - -The example below shows a simple IAM policy that allows the backend operations role to perform these operations: +DynamoDB does not assign a separate resource ARN to each key in a table, but you can write more precise policies for a DynamoDB table [using an IAM `Condition` element](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/specifying-conditions.html). +For example, you can use the `dynamodb:LeadingKeys` condition key to match on the partition key values that the S3 backend will use: ```json { "Version": "2012-10-17", "Statement": [ - { - "Effect" : "Allow", - "Action" : [ - "dynamodb:DeleteItem", - "dynamodb:GetItem", - "dynamodb:PutItem", - "dynamodb:Query", - "dynamodb:UpdateItem" - ], - "Resource" : ["arn:aws:dynamodb:*:*:table/myorg-state-lock-table"], - "Condition" : { - "ForAllValues:StringEquals" : { - "dynamodb:LeadingKeys" : [ - "myorg-terraform-states/myapp/production/tfstate", // during a state lock the full state file is stored with this key - "myorg-terraform-states/myapp/production/tfstate-md5" // after the lock is released a hash of the statefile's contents are stored with this key - ] - } + { + "Effect": "Allow", + "Action": [ + "dynamodb:DeleteItem", + "dynamodb:GetItem", + "dynamodb:PutItem" + ], + "Resource": "arn:aws:dynamodb:us-east-1:12341234:table/TableName", + "Condition": { + "ForAllValues:StringEquals": { + "dynamodb:LeadingKeys": [ + "TableName/myapp/production/tfstate", + "TableName/myapp/production/tfstate-md5" + ] } } + } ] } ``` -The example backend configuration below documents the corresponding `dynamodb_table` -argument: +Note that DynamoDB ARNs are regional and account-specific, unlike S3 bucket ARNs, so you must also specify the correct region and AWS account ID for your DynamoDB table in the `Resource` element. + +The example backend configuration below documents the corresponding arguments: ```hcl terraform { @@ -579,7 +575,7 @@ terraform { bucket = "myorg-terraform-states" key = "myapp/production/tfstate" region = "us-east-1" - dynamodb_table = "myorg-state-lock-table" + dynamodb_table = "TableName } } ```