How to Create AWS IAM Policy Using Terraform

In AWS, IAM service is used to control access to services and resources of AWS. It needs a very in-depth knowledge to configure IAM policies to assure minimum privileges to AWS systems and resources.

Built for the purpose of Infrastructure as Code (IaC) Solution, Terraform supports multiple cloud service providers. It is an Open source tool developed by HashiCorp. Using IaC, we can manage infrastructure setup with configuration files. For example, we can deploy, update, and manage our infrastructure by defining the required resources.

In this guide, we will see how we can create an AWS user and attach a policy to it using Terraform. Let us first start with the installation of Terraform on Ubuntu 20.04.

Installing Terraform

Hashicorp provides the official Terraform package for Ubuntu/Debian, CentOS/RHEL, Fedora and Amazon Linux. Beside this, it also maintains pre-compiled binary and can also be compiled from source. For this guide, we are using the default package provided by the Debian package repository to install Terraform on Ubuntu 20.04.

Step 1. Install gnupg, software-properties-common, and curl packages to verify HashiCorp’s GPG signature and install the required repository:

$ sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl

Step 2. Add the HashiCorp GPG key using the command:

$ curl -fsSL | sudo apt-key add -

Step 3. Continue by adding the required repository.

$ sudo apt-add-repository "deb [arch=amd64] $(lsb_release -cs) main"

Step 4. Run the update command to add the repository and install terraform.

$ sudo apt-get update && sudo apt-get install terraform

Step 5. Verify if Terraform is installed by running the command:

$ terraform -version

Our Terraform is installed on our local machine, so we can continue our task in working with AWS. As mentioned earlier, Terraform uses several configuration files for provisioning resources. Each of these files must reside in their respective working folder/directory. Let us create a directory for this purpose.

Make a folder to contain your configuration files and change directory to this folder:

$ mkdir linuxhint-terraform && cd linuxhint-terraform

1. Creating IAM user using Terraform

We have only one IAM user right now:

We will now make a ‘’ file that will be used for creating our user ‘DemoUser’:

$ nano

Now put the following configuration inside it:

terraform {
required_providers {
    aws = {
    source  = "hashicorp/aws"
    version = "~> 3.27"

required_version = ">= 0.14.9"

provider "aws" {
  region    = "us-east-1"
access_key = "your_access_key_for_current_user"
secret_key = "your_secret_key_for_current_user"

resource "aws_iam_user" "new_user" {
  name = "DemoUser"

resource "aws_iam_access_key" "AccK" {
  user =

output "secret_key" {
  value = aws_iam_access_key.AccK.secret
  sensitive = true

output "access_key" {
  value =

2. Creating a policy and attaching it to the IAM user using Terraform

We will create an S3 list all buckets policy and attach it to our IAM user. Now append the above file with this code:

resource "aws_iam_user_policy" "iam" {
  name = "test"
  user =

  policy = <<EOF
    "Version": "2012-10-17",
    "Statement": [
    "Effect": "Allow",
    "Action": "s3:ListAllMyBuckets",
    "Resource": "*"

This file contains the whole configuration to be deployed using Terraform. Just replace the bolded text with your own configuration details. Let us explore each of the sections used in the above file:

  • terraform – it defines the Terraform settings. The ‘required providers’ defines the provider to use with the Terraform and the ‘source’ is an optional parameter for hostname, a namespace and the provider type. In above code the source is defined as ‘hashicorp/aws’ which like all providers is installed from the Terraform registry. The above provider points to ‘’.

The version attribute defines the version of the provider you want to use.

  • Provider – this actually specifies which cloud platform you are going to interact with(AWS, Azure, GCP etc.). This also controls the region you are deploying your resources and the security credentials for your user.
  • Resource – it comprises components that build an infrastructure like databases, storage, network etc. The first string, here “aws_instance”, defines the resource type and the second one defines a custom name you want to use. These two combine to form a unique ID for a resource, for e.g. here ‘aws_iam_access_key.AccK.secret’ is a resource identifier (ID). In the same way, we can also include machine sizes, disk image names, or VPC IDs.

To validate or verify your configuration use the command:

$ terraform validate

Initializing the Terraform Directory

To download and install the provider we defined in our configuration and other files, we need to initialize the directory containing this file:

$ terraform init

As you can see from the above picture, our init command is successful and there are some new files also created here. There is also one more command: ‘terraform plan’. Although it is not mandatory to use it, it has some benefits. For example.:

1. You can see the actions Terraform is going to perform.

2. It can point out syntactical errors in your configuration files.

Terraform does not mention this command in its documentation because when you run the ‘terraform apply’ command, the same plan will be again presented.

Building the Infrastructure

To build our infrastructure, use the command:

$ terraform apply

This will first output the execution plan describing the tasks that terraform will perform to bring the state of your infrastructure to the one defined in your configuration file. After this, it will pause and ask you to confirm the plan to continue. If everything is set as you desired, type ‘yes’ to continue:

If you are ready to continue, type ‘yes’. Note that completing the process takes some time. When this process is complete, the below message will appear:

To view your security credentials, open the ‘terraform.tfstate’ file and look for the value attribute under the “secret_key” and “access_key”:

On your AWS IAM management console, the IAM user will be listed there:

In order to check which policy is attached to this IAM user, click on the IAM user’s name. From the below screenshot, we can see that or ‘DemoUser’ has a ‘test’ policy attached to it with the same permission we attached earlier in the terraform file.

Verifying the Policy

To see if our attached policy is working as expected, connect to the IAM user and run the command:

$ aws s3 ls

If everything has been set up correctly, you will see the list of your buckets here:

Destroying the Resources

When you are finished and do not longer need the aws resources you created, you can simply delete them by using the command:

$ terraform destroy


In this guide, we have learned about attaching an IAM policy to an AWS user using Terraform. You can also try attaching different policies to a user or role in the same way.

About the author

Ali Imran Nagori

Ali imran is a technical writer and Linux enthusiast who loves to write about Linux system administration and related technologies. You can connect with him on LinkedIn