diff --git a/website/aws.erb b/website/aws.erb
index 0bfa244031f..649bcf97f78 100644
--- a/website/aws.erb
+++ b/website/aws.erb
@@ -22,6 +22,10 @@
AWS EKS Getting Started
+
>
+ AWS IAM Policy Documents
+
+
>
AWS Lambda with API Gateway
diff --git a/website/docs/d/iam_policy_document.html.markdown b/website/docs/d/iam_policy_document.html.markdown
index 3983aa17e39..9448f703a71 100644
--- a/website/docs/d/iam_policy_document.html.markdown
+++ b/website/docs/d/iam_policy_document.html.markdown
@@ -14,6 +14,8 @@ This is a data source which can be used to construct a JSON representation of
an IAM policy document, for use with resources which expect policy documents,
such as the `aws_iam_policy` resource.
+-> For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
+
```hcl
data "aws_iam_policy_document" "example" {
statement {
diff --git a/website/docs/guides/iam-policy-documents.html.md b/website/docs/guides/iam-policy-documents.html.md
new file mode 100644
index 00000000000..db11489fd96
--- /dev/null
+++ b/website/docs/guides/iam-policy-documents.html.md
@@ -0,0 +1,169 @@
+---
+layout: "aws"
+page_title: "AWS IAM Policy Documents with Terraform"
+sidebar_current: "docs-aws-guide-iam-policy-documents"
+description: |-
+ Using Terraform to configure AWS IAM policy documents.
+---
+
+# AWS IAM Policy Documents with Terraform
+
+AWS leverages a standard JSON Identity and Access Management (IAM) policy document format across many services to control authorization to resources and API actions. This guide is designed to highlight some recommended configuration patterns with how Terraform and the AWS provider can build these policy documents.
+
+The example policy documents and resources in this guide are for illustrative purposes only. Full documentation about the IAM policy format and supported elements can be found in the [AWS IAM User Guide](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html).
+
+~> **NOTE:** Some AWS services only allow a subset of the policy elements or policy variables. For more information, see the AWS User Guide for the service you are configuring.
+
+~> **NOTE:** [IAM policy variables](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html), e.g. `${aws:username}`, use the same configuration syntax (`${...}`) as Terraform interpolation. When implementing IAM policy documents with these IAM variables, you may receive syntax errors from Terraform. You can escape the dollar character within your Terraform configration to prevent the error, e.g. `$${aws:username}`.
+
+
+
+- [Choosing a Configuration Method](#choosing-a-configuration-method)
+- [Recommended Configuration Method Examples](#recommended-configuration-method-examples)
+ - [aws_iam_policy_document Data Source](#aws_iam_policy_document-data-source)
+ - [Multiple Line Heredoc Syntax](#multiple-line-heredoc-syntax)
+- [Other Configuration Method Examples](#other-configuration-method-examples)
+ - [Single Line String Syntax](#single-line-string-syntax)
+ - [file() Interpolation Function](#file-interpolation-function)
+ - [template_file Data Source](#template_file-data-source)
+
+
+
+## Choosing a Configuration Method
+
+Terraform offers flexibility when creating configurations to match the architectural structure of teams and infrastructure. In most situations, using native functionality within Terraform and its providers will be the simplest to understand, eliminating context switching with other tooling, file sprawl, or differing file formats. Configuration examples of the available methods can be found later in the guide.
+
+The recommended approach to building AWS IAM policy documents within Terraform is the highly customizable [`aws_iam_policy_document` data source](#aws_iam_policy_document-data-source). A short list of benefits over other methods include:
+
+- Native Terraform configuration - no need to worry about JSON formatting or syntax
+- Policy layering - create policy documents that combine and/or overwrite other policy documents
+- Built-in policy error checking
+
+Otherwise in simple cases, such as a statically defined [assume role policy for an IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_permissions-to-switch.html), Terraform's [multiple line heredoc syntax](#multiple-line-heredoc-syntax) allows the easiest formatting without any indirection of a separate data source configuration or file.
+
+Additional methods are available, such [single line string syntax](#single-line-string-syntax), the [file() interpolation function](#file-interpolation-function), and the [template_file data source](#template_file-data-source), however their usage is discouraged due to their complexity.
+
+## Recommended Configuration Method Examples
+
+These configuration methods are the simplest and most powerful within Terraform.
+
+### aws_iam_policy_document Data Source
+
+-> For complete implementation information and examples, see the [`aws_iam_policy_document` data source documentation](/docs/providers/aws/d/iam_policy_document.html).
+
+```hcl
+data "aws_iam_policy_document" "example" {
+ statement {
+ actions = ["*"]
+ resources = ["*"]
+ }
+}
+
+resource "aws_iam_policy" "example" {
+ # ... other configuration ...
+
+ policy = "${data.aws_iam_policy_document.example.json}"
+}
+```
+
+### Multiple Line Heredoc Syntax
+
+Interpolation is available within the heredoc string if necessary.
+
+For example:
+
+```hcl
+resource "aws_iam_policy" "example" {
+ # ... other configuration ...
+ policy = < **NOTE:** The AWS ECR API seems to reorder rules based on `rulePriority`. If you define multiple rules that are not sorted ascending in the TF code will be flagged for recreation every `terraform plan`.
diff --git a/website/docs/r/ecr_repository_policy.html.markdown b/website/docs/r/ecr_repository_policy.html.markdown
index e0188df74f5..de269865682 100644
--- a/website/docs/r/ecr_repository_policy.html.markdown
+++ b/website/docs/r/ecr_repository_policy.html.markdown
@@ -62,7 +62,7 @@ EOF
The following arguments are supported:
* `repository` - (Required) Name of the repository to apply the policy.
-* `policy` - (Required) The policy document. This is a JSON formatted string.
+* `policy` - (Required) The policy document. This is a JSON formatted string. For more information about building IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html)
## Attributes Reference
diff --git a/website/docs/r/iam_group_policy.html.markdown b/website/docs/r/iam_group_policy.html.markdown
index 4a182ccb96d..ab22efad963 100644
--- a/website/docs/r/iam_group_policy.html.markdown
+++ b/website/docs/r/iam_group_policy.html.markdown
@@ -43,8 +43,7 @@ resource "aws_iam_group" "my_developers" {
The following arguments are supported:
-* `policy` - (Required) The policy document. This is a JSON formatted string.
- The heredoc syntax or `file` function is helpful here.
+* `policy` - (Required) The policy document. This is a JSON formatted string. For more information about building IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html)
* `name` - (Optional) The name of the policy. If omitted, Terraform will
assign a random, unique name.
* `name_prefix` - (Optional) Creates a unique name beginning with the specified
diff --git a/website/docs/r/iam_policy.html.markdown b/website/docs/r/iam_policy.html.markdown
index c5b23023d01..ee299962ffa 100644
--- a/website/docs/r/iam_policy.html.markdown
+++ b/website/docs/r/iam_policy.html.markdown
@@ -44,10 +44,7 @@ The following arguments are supported:
* `name_prefix` - (Optional, Forces new resource) Creates a unique name beginning with the specified prefix. Conflicts with `name`.
* `path` - (Optional, default "/") Path in which to create the policy.
See [IAM Identifiers](https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) for more information.
-* `policy` - (Required) The policy document. This is a JSON formatted string.
- The heredoc syntax, `file` function, or the [`aws_iam_policy_document` data
- source](/docs/providers/aws/d/iam_policy_document.html)
- are all helpful here.
+* `policy` - (Required) The policy document. This is a JSON formatted string. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html)
## Attributes Reference
diff --git a/website/docs/r/iam_role_policy.html.markdown b/website/docs/r/iam_role_policy.html.markdown
index 568c3c93b0d..482aaedac0c 100644
--- a/website/docs/r/iam_role_policy.html.markdown
+++ b/website/docs/r/iam_role_policy.html.markdown
@@ -62,8 +62,7 @@ The following arguments are supported:
assign a random, unique name.
* `name_prefix` - (Optional) Creates a unique name beginning with the specified
prefix. Conflicts with `name`.
-* `policy` - (Required) The policy document. This is a JSON formatted string.
- The heredoc syntax or `file` function is helpful here.
+* `policy` - (Required) The policy document. This is a JSON formatted string. For more information about building IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html)
* `role` - (Required) The IAM role to attach to the policy.
## Attributes Reference
diff --git a/website/docs/r/iam_user_policy.html.markdown b/website/docs/r/iam_user_policy.html.markdown
index 5551c69ccdd..4490b936129 100644
--- a/website/docs/r/iam_user_policy.html.markdown
+++ b/website/docs/r/iam_user_policy.html.markdown
@@ -47,8 +47,7 @@ resource "aws_iam_access_key" "lb" {
The following arguments are supported:
-* `policy` - (Required) The policy document. This is a JSON formatted string.
- The heredoc syntax or `file` function is helpful here.
+* `policy` - (Required) The policy document. This is a JSON formatted string. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
* `name` - (Optional) The name of the policy. If omitted, Terraform will assign a random, unique name.
* `name_prefix` - (Optional, Forces new resource) Creates a unique name beginning with the specified prefix. Conflicts with `name`.
* `user` - (Required) IAM user to which to attach this policy.
diff --git a/website/docs/r/iot_policy.html.markdown b/website/docs/r/iot_policy.html.markdown
index ba28fe71efd..f8b191c44b8 100644
--- a/website/docs/r/iot_policy.html.markdown
+++ b/website/docs/r/iot_policy.html.markdown
@@ -37,9 +37,7 @@ EOF
The following arguments are supported:
* `name` - (Required) The name of the policy.
-* `policy` - (Required) The policy document. This is a JSON formatted string.
- The heredoc syntax or `file` function is helpful here. Use the [IoT Developer Guide]
- (http://docs.aws.amazon.com/iot/latest/developerguide/iot-policies.html) for more information on IoT Policies
+* `policy` - (Required) The policy document. This is a JSON formatted string. Use the [IoT Developer Guide](http://docs.aws.amazon.com/iot/latest/developerguide/iot-policies.html) for more information on IoT Policies. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
## Attributes Reference
diff --git a/website/docs/r/kms_key.html.markdown b/website/docs/r/kms_key.html.markdown
index f63e425f14b..b70aa5989dd 100644
--- a/website/docs/r/kms_key.html.markdown
+++ b/website/docs/r/kms_key.html.markdown
@@ -26,7 +26,7 @@ The following arguments are supported:
* `description` - (Optional) The description of the key as viewed in AWS console.
* `key_usage` - (Optional) Specifies the intended use of the key.
Defaults to ENCRYPT_DECRYPT, and only symmetric encryption and decryption are supported.
-* `policy` - (Optional) A valid policy JSON document.
+* `policy` - (Optional) A valid policy JSON document. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
* `deletion_window_in_days` - (Optional) Duration in days after which the key is deleted
after destruction of the resource, must be between 7 and 30 days. Defaults to 30 days.
* `is_enabled` - (Optional) Specifies whether the key is enabled. Defaults to true.
diff --git a/website/docs/r/media_store_container_policy.html.markdown b/website/docs/r/media_store_container_policy.html.markdown
index 0f38e6368de..8e305da8825 100644
--- a/website/docs/r/media_store_container_policy.html.markdown
+++ b/website/docs/r/media_store_container_policy.html.markdown
@@ -46,7 +46,7 @@ EOF
The following arguments are supported:
* `container_name` - (Required) The name of the container.
-* `policy` - (Required) The contents of the policy.
+* `policy` - (Required) The contents of the policy. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
## Import
diff --git a/website/docs/r/s3_bucket.html.markdown b/website/docs/r/s3_bucket.html.markdown
index 7d68b04a432..b37e3c572b0 100644
--- a/website/docs/r/s3_bucket.html.markdown
+++ b/website/docs/r/s3_bucket.html.markdown
@@ -320,7 +320,7 @@ The following arguments are supported:
* `bucket` - (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name.
* `bucket_prefix` - (Optional, Forces new resource) Creates a unique bucket name beginning with the specified prefix. Conflicts with `bucket`.
* `acl` - (Optional) The [canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) to apply. Defaults to "private".
-* `policy` - (Optional) A valid [bucket policy](https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html) JSON document. Note that if the policy document is not specific enough (but still valid), Terraform may view the policy as constantly changing in a `terraform plan`. In this case, please make sure you use the verbose/specific version of the policy.
+* `policy` - (Optional) A valid [bucket policy](https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html) JSON document. Note that if the policy document is not specific enough (but still valid), Terraform may view the policy as constantly changing in a `terraform plan`. In this case, please make sure you use the verbose/specific version of the policy. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
* `tags` - (Optional) A mapping of tags to assign to the bucket.
* `force_destroy` - (Optional, Default:false ) A boolean that indicates all objects should be deleted from the bucket so that the bucket can be destroyed without error. These objects are *not* recoverable.
diff --git a/website/docs/r/s3_bucket_policy.html.markdown b/website/docs/r/s3_bucket_policy.html.markdown
index cee15f1864b..80d08ae2e3b 100644
--- a/website/docs/r/s3_bucket_policy.html.markdown
+++ b/website/docs/r/s3_bucket_policy.html.markdown
@@ -47,4 +47,4 @@ POLICY
The following arguments are supported:
* `bucket` - (Required) The name of the bucket to which to apply the policy.
-* `policy` - (Required) The text of the policy.
+* `policy` - (Required) The text of the policy. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
diff --git a/website/docs/r/secretsmanager_secret.html.markdown b/website/docs/r/secretsmanager_secret.html.markdown
index 74cc8c565b4..61e36665de0 100644
--- a/website/docs/r/secretsmanager_secret.html.markdown
+++ b/website/docs/r/secretsmanager_secret.html.markdown
@@ -46,7 +46,7 @@ The following arguments are supported:
* `name` - (Required) Specifies the friendly name of the new secret. The secret name can consist of uppercase letters, lowercase letters, digits, and any of the following characters: `/_+=.@-` Spaces are not permitted.
* `description` - (Optional) A description of the secret.
* `kms_key_id` - (Optional) Specifies the ARN or alias of the AWS KMS customer master key (CMK) to be used to encrypt the secret values in the versions stored in this secret. If you don't specify this value, then Secrets Manager defaults to using the AWS account's default CMK (the one named `aws/secretsmanager`). If the default KMS CMK with that name doesn't yet exist, then AWS Secrets Manager creates it for you automatically the first time.
-* `policy` - (Optional) A valid JSON document representing a [resource policy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-based-policies.html).
+* `policy` - (Optional) A valid JSON document representing a [resource policy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-based-policies.html). For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
* `recovery_window_in_days` - (Optional) Specifies the number of days that AWS Secrets Manager waits before it can delete the secret. This value can be `0` to force deletion without recovery or range from `7` to `30` days. The default value is `30`.
* `rotation_lambda_arn` - (Optional) Specifies the ARN of the Lambda function that can rotate the secret.
* `rotation_rules` - (Optional) A structure that defines the rotation configuration for this secret. Defined below.
diff --git a/website/docs/r/sns_topic.html.markdown b/website/docs/r/sns_topic.html.markdown
index 035b62dc392..c508bc3ca06 100644
--- a/website/docs/r/sns_topic.html.markdown
+++ b/website/docs/r/sns_topic.html.markdown
@@ -56,7 +56,7 @@ The following arguments are supported:
* `name` - (Optional) The friendly name for the SNS topic. By default generated by Terraform.
* `name_prefix` - (Optional) The friendly name for the SNS topic. Conflicts with `name`.
* `display_name` - (Optional) The display name for the SNS topic
-* `policy` - (Optional) The fully-formed AWS policy as JSON
+* `policy` - (Optional) The fully-formed AWS policy as JSON. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
* `delivery_policy` - (Optional) The SNS delivery policy. More on [AWS documentation](https://docs.aws.amazon.com/sns/latest/dg/DeliveryPolicies.html)
* `application_success_feedback_role_arn` - (Optional) The IAM role permitted to receive success feedback for this topic
* `application_success_feedback_sample_rate` - (Optional) Percentage of success to sample
diff --git a/website/docs/r/sns_topic_policy.html.markdown b/website/docs/r/sns_topic_policy.html.markdown
index e3941f6a645..7526db7a4fd 100644
--- a/website/docs/r/sns_topic_policy.html.markdown
+++ b/website/docs/r/sns_topic_policy.html.markdown
@@ -71,4 +71,4 @@ data "aws_iam_policy_document" "sns-topic-policy" {
The following arguments are supported:
* `arn` - (Required) The ARN of the SNS topic
-* `policy` - (Required) The fully-formed AWS policy as JSON
+* `policy` - (Required) The fully-formed AWS policy as JSON. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
diff --git a/website/docs/r/sqs_queue.html.markdown b/website/docs/r/sqs_queue.html.markdown
index 5a07d42cf9b..2d69f2ce80a 100644
--- a/website/docs/r/sqs_queue.html.markdown
+++ b/website/docs/r/sqs_queue.html.markdown
@@ -56,7 +56,7 @@ The following arguments are supported:
* `max_message_size` - (Optional) The limit of how many bytes a message can contain before Amazon SQS rejects it. An integer from 1024 bytes (1 KiB) up to 262144 bytes (256 KiB). The default for this attribute is 262144 (256 KiB).
* `delay_seconds` - (Optional) The time in seconds that the delivery of all messages in the queue will be delayed. An integer from 0 to 900 (15 minutes). The default for this attribute is 0 seconds.
* `receive_wait_time_seconds` - (Optional) The time for which a ReceiveMessage call will wait for a message to arrive (long polling) before returning. An integer from 0 to 20 (seconds). The default for this attribute is 0, meaning that the call will return immediately.
-* `policy` - (Optional) The JSON policy for the SQS queue
+* `policy` - (Optional) The JSON policy for the SQS queue. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
* `redrive_policy` - (Optional) The JSON policy to set up the Dead Letter Queue, see [AWS docs](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/SQSDeadLetterQueue.html). **Note:** when specifying `maxReceiveCount`, you must specify it as an integer (`5`), and not a string (`"5"`).
* `fifo_queue` - (Optional) Boolean designating a FIFO queue. If not set, it defaults to `false` making it standard.
* `content_based_deduplication` - (Optional) Enables content-based deduplication for FIFO queues. For more information, see the [related documentation](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html#FIFO-queues-exactly-once-processing)
diff --git a/website/docs/r/sqs_queue_policy.html.markdown b/website/docs/r/sqs_queue_policy.html.markdown
index 579a54d8be7..b3ab3419237 100644
--- a/website/docs/r/sqs_queue_policy.html.markdown
+++ b/website/docs/r/sqs_queue_policy.html.markdown
@@ -49,7 +49,7 @@ POLICY
The following arguments are supported:
* `queue_url` - (Required) The URL of the SQS Queue to which to attach the policy
-* `policy` - (Required) The JSON policy for the SQS queue
+* `policy` - (Required) The JSON policy for the SQS queue. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
## Import
diff --git a/website/docs/r/vpc_endpoint.html.markdown b/website/docs/r/vpc_endpoint.html.markdown
index b6efd4d6bd9..bbd261d1505 100644
--- a/website/docs/r/vpc_endpoint.html.markdown
+++ b/website/docs/r/vpc_endpoint.html.markdown
@@ -85,8 +85,7 @@ The following arguments are supported:
* `vpc_endpoint_type` - (Optional) The VPC endpoint type, `Gateway` or `Interface`. Defaults to `Gateway`.
* `service_name` - (Required) The service name, in the form `com.amazonaws.region.service` for AWS services.
* `auto_accept` - (Optional) Accept the VPC endpoint (the VPC endpoint and service need to be in the same AWS account).
-* `policy` - (Optional) A policy to attach to the endpoint that controls access to the service. Applicable for endpoints of type `Gateway`.
-Defaults to full access.
+* `policy` - (Optional) A policy to attach to the endpoint that controls access to the service. Applicable for endpoints of type `Gateway`. Defaults to full access. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
* `route_table_ids` - (Optional) One or more route table IDs. Applicable for endpoints of type `Gateway`.
* `subnet_ids` - (Optional) The ID of one or more subnets in which to create a network interface for the endpoint. Applicable for endpoints of type `Interface`.
* `security_group_ids` - (Optional) The ID of one or more security groups to associate with the network interface. Required for endpoints of type `Interface`.