You must assign explicit permissions to IAM identities (users, groups, or roles) to enable their access AWS resources. The associated IAM policy determines the privileges available to an IAM identity. Policies are JSON documents that define explicit allow/deny privileges to specific resources or resource groups.
There are advantages to managing IAM policies in Terraform rather than manually in AWS. With Terraform, you can reuse your policy templates and ensure the principle of least privilege with resource interpolation.
In this tutorial, you will create an IAM user and an S3 bucket. Then, you will map permissions for that bucket with an IAM policy. Finally, you will attach that policy to the new user and learn how to iterate on more complex policies.
You can complete this tutorial using the same workflow with either Terraform Community Edition or HCP Terraform. HCP Terraform is a platform that you can use to manage and execute your Terraform projects. It includes features like remote state and execution, structured plan output, workspace resource summaries, and more.
Select the Terraform Community Edition tab to complete this tutorial using Terraform Community Edition.
Clone the Create IAM policies with Terraform repository.
$ git clone https://github.com/hashicorp-education/learn-terraform-iam-policy
Change into the repository directory.
$ cd learn-terraform-iam-policy
The IAM policy resource is the starting point for creating an IAM policy in Terraform.
The main.tf
file contains an IAM policy resource, an S3 bucket, and a new IAM user. Open the main.tf
file in your code editor and review the IAM policy resource. The name
in your policy is a random_pet
string to avoid duplicate policy names.
main.tf
resource "aws_iam_policy" "policy" {
name = "${random_pet.pet_name.id}-policy"
description = "My test policy"
policy = <<EOT
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListAllMyBuckets"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": "${aws_s3_bucket.bucket.arn}"
}
]
}
EOT
}
The resource's policy
attribute uses a multi-line heredoc string. For simple policies or one-off configurations, this approach is acceptable. However, as your policies grow more complex and you begin to reuse them throughout your environment, it can be difficult to parse policies using heredoc strings.
The aws_iam_policy_document
data source uses HCL to generate a JSON representation of an IAM policy document. Writing the policy as a Terraform configuration has several advantages over defining your policy inline in the aws_iam_policy
resource.
source_policy_documents
and override_policy_documents
arguments.Copy the aws_iam_policy_document
configuration below into your main.tf
file. This data source uses HCL syntax to define the same IAM privileges as the policy in the heredoc string.
main.tf
data "aws_iam_policy_document" "example" {
statement {
actions = ["s3:ListAllMyBuckets"]
resources = ["arn:aws:s3:::*"]
effect = "Allow"
}
statement {
actions = ["s3:*"]
resources = [aws_s3_bucket.bucket.arn]
effect = "Allow"
}
}
Both statements in this policy apply to any user, group, or role with this policy attached. The first policy statement allows the user to list every S3 bucket in the AWS account. The second policy statement allows the user to perform any action on the bucket you create in this configuration, but not on other buckets in the account.
Update your iam_policy
resource policy
attribute to use the IAM policy document and save your changes.
main.tf
resource "aws_iam_policy" "policy" {
name = "${random_pet.pet_name.id}-policy"
description = "My test policy"
+ policy = data.aws_iam_policy_document.example.json
- policy = <<EOT
- {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Action": [
- "s3:ListAllMyBuckets"
- ],
- "Effect": "Allow",
- "Resource": "*"
- },
- {
- "Action": [
- "s3:*"
- ],
- "Effect": "Allow",
- "Resource": "${aws_s3_bucket.bucket.arn}"
- }
- ]
- }
- EOT
}
The iam_policy
resource and iam_policy_document
data source used together will create a policy, but this configuration does not apply this policy to any users or roles. You must create a policy attachment for your policy to apply to your users.
In your main.tf
file, add a new policy attachment resource to apply your policy to the user created in this configuration.
main.tf
resource "aws_iam_user_policy_attachment" "attachment" {
user = aws_iam_user.new_user.name
policy_arn = aws_iam_policy.policy.arn
}
The policy attachment resource has two required attributes: the user
and the policy_arn
. Terraform interpolates your policy Amazon Resource Name (ARN) from your previously defined iam_policy
resource when you apply this configuration. Each AWS resource has an ARN, and Terraform passes that unique identifier to the AWS API.
This resource assigns your policy to a specific user. If you are creating a group or a role, you can use the group or role attachment resources instead.
Add an output for your JSON-rendered policy to the end of your outputs.tf
file.
outputs.tf
output "rendered_policy" {
value = data.aws_iam_policy_document.example.json
}
Now that you have created and attached a policy in your configuration, apply your changes.
Set the TF_CLOUD_ORGANIZATION
environment variable to your HCP Terraform organization name. This will configure your HCP Terraform integration.
$ export TF_CLOUD_ORGANIZATION=
$ $Env:TF_CLOUD_ORGANIZATION = ""
$ set "TF_CLOUD_ORGANIZATION="
In your terminal, initialize your Terraform configuration. Terraform will automatically create the learn-terraform-aws-iam-policy
workspace in your HCP Terraform organization.
$ terraform init
Initializing HCP Terraform...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Installing hashicorp/aws v4.4.0...
- Installed hashicorp/aws v4.4.0 (signed by HashiCorp)
HCP Terraform has been successfully initialized!
You may now begin working with HCP Terraform. Try running "terraform plan" to
see any changes that are required for your infrastructure.
If you ever set or change modules or Terraform Settings, run "terraform init"
again to reinitialize your working directory.
Open your terraform.tf
file and comment out the cloud
block that configures the HCP Terraform integration.
terraform.tf
terraform {
/*
cloud {
workspaces {
name = "learn-terraform-aws-iam-policy"
}
}
*/
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.4.0"
}
}
required_version = ">= 1.2"
}
Initialize this configuration.
$ terraform init
Initializing the backend...
##...
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Apply your configuration. Enter yes
when prompted to accept your changes.
$ terraform apply
## ...
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
Outputs:
rendered_policy = <<EOT
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
},
{
"Sid": "",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::primarily-liberal-spider-bucket"
}
]
}
EOT
The output should contain a rendered policy with the complete ARN of your newly created bucket.
Test this policy in the AWS Policy Simulator. This tool lets you test an IAM policy by simulating whether a user would be allowed to run AWS operations.
Use the Policy Simulator to test if your user can delete any objects or buckets in the S3 service.
new_user
, then your policy name from the left sidebar. Your policy name should start with your random animal and -policy-
.
Next, test if your user can delete objects in the test bucket you created or delete the bucket itself.
arn:aws:s3:::<RANDOM_ANIMAL>-bucket-
.*
character.
Before moving on, destroy the infrastructure you created in this tutorial.
Respond to the confirmation prompt with yes.
If you used HCP Terraform for this tutorial, after destroying your resources, delete the learn-terraform-aws-iam-policy
workspace from your HCP Terraform organization.
In this tutorial, you created and refactored an AWS IAM policy with Terraform. To learn more about creating policies with Terraform, consider the resources below.
templatefile()
function allows you to create templatized policies for use in your configuration.jsonencode()
function.RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4