Amazon AWS

How to Create IAM User & Policy using Terraform on AWS

Hello. In this tutorial, we will create an IAM policy and user using Terraform on AWS.

Terraform is a popular open-source deployment automation software. 

1. Introduction

Terraform is a tool for building, changing, and versioning the infrastructure safely and efficiently. It is used to manage the infrastructure of the popular cloud service providers and custom in-house solutions. It helps manage both low-level (Compute, Storage, Networking, etc.) and high-level components (such as SaaS, DNS, etc.) Terraform deployment automation is divided into different sections i.e.

  • IaaC – IaaC is popularly known as the Infrastructure as a Code wherein the infrastructure is described using a high-level configuration syntax. This allows a blueprint of the infrastructure which can be deployed, versioned, and shared for re-use
  • Execution Plans – Terraform has a planning step where it generates an execution plan. The execution plan tells the administrator what Terraform will do once applied and helps to avoid any surprises when it creates the infrastructure
  • Resource Graph – Terraform builds a graph of all the resources and parallelizes the creation and modification of non-dependent resources. This offers insights into learning the dependencies in their infrastructure
  • Change Automation – Terraform allows to apply of complex changesets to the infrastructure with minimal human intervention

1.1 Configuration language

Terraform has its configuration language designed to meet the infrastructure automation requirements. The main purpose of this language is to declare resources and a group of resources (gathered into a module) represents a larger unit of configuration. Language syntax consists of few elements i.e. – Blocks, Arguments, and Expressions.

  • Blocks – Containers for other contents and represents the object configuration
  • Arguments – Assign a value to the name and appear within the blocks
  • Expressions – Represents a single value, referenced value, or combination of other values

1.2 Steps

To create the infrastructure via the Terraform scripts following commands need to be executed.

  • terraform init – Initializing the new or existing terraform configuration
  • terraform plan – Generate the execution plan from the resources specified in the file
  • terraform apply – Create the infrastructure from the resources specified in the file

2. Practice

Let us dive into some practice stuff from here. You’re free to choose the IDE of your choice. I am using Visual Studio Code as my preferred IDE for the development with the HashiCorp Terraform extension installed. The extension offers syntax highlighting and other editing features for Terraform files using the Terraform language server.

2.1 Pre-requisite

To proceed we will be needing an AWS CLI user having the right set of permissions required for creating the infrastructure. I am using an existing user and attached the IAM full access policy attached to this user so that the IAM user can successfully create the required infrastructure. The access and secret key generated for the user will be used in the file.

2.2 Provider File

The provider file lists the plugin that allows for the full lifecycle management of cloud resources. In our case, we will be using the AWS provider. The block consists of the details that will be used to connect with the AWS cloud.

  • region – The attribute for setting up the infrastructure. This is a mandatory field that cannot be skipped and can be referenced via the variables
  • access_key and secret_key – The CLI user credentials will be responsible for setting up the infrastructure. Remember that the user must have the required policies assigned to set up the infrastructure. Since this is an optional field; many a time developers like to use the profile attribute in case they don’t want to hardcode the credentials in the terraform file

Add the following code to the file.

provider "aws" {
  region = var.region
  # aws cli user credentials
  # user should have the administration policy or policy as per the lpp principle
  access_key = "your_access_key"
  secret_key = "your_secret_key"

2.3 Variables File

The file contains the declarations to be used across the terraform module. Add the following code to the file containing the region-code and usernames variable.

variable "region" {
  type        = string
  description = "iam region"
  # my fav. choice is : ap-south-1
  default = "your_region"
variable "usernames" {
  type        = list(any)
  description = "list of users"
  default     = ["geek1", "geek2"]

2.4 Policy File

The file contains the policy resource that will be used to define the policy according to the necessities. For example, allowing the IAM user to access the S3 bucket, etc. policy attribute is a required parameter.

# policy creation
# iam readonly access policy for iam users
resource "aws_iam_policy" "iamreadonlyaccess" {
  name        = "iamreadonlyaccess"
  description = "iamreadonlyaccess"
  /* jsonencode better than EOF. EOF breaks the new terraform code. */
  policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
        "Sid" : "VisualEditor0",
        "Effect" : "Allow",
        "Action" : [
        "Resource" : "*"
  tags = {
    "createdby" = "terraform"

# optional - if you don't generate the pwd from the terraform script comment the below resource
# account password change policy after first login
# resource "aws_iam_account_password_policy" "strict" {
#   minimum_password_length        = 8
#   require_lowercase_characters   = true
#   require_uppercase_characters   = true
#   require_numbers                = true
#   require_symbols                = true
#   allow_users_to_change_password = true
# }

2.5 User File

The file contains the resources that will be used to define the users and map the created users to a policy (named – iamreadonlyaccess). Add the following code to it.

# user creation
resource "aws_iam_user" "newusers" {
  count = length(var.usernames)
  name  = element(var.usernames, count.index)
  tags = {
    "createdby" = "terraform"

# attaching "iamreadonlyaccess" policy to the user
resource "aws_iam_user_policy_attachment" "usrpolicyrelationship" {
  depends_on = [aws_iam_policy.iamreadonlyaccess]
  count      = length(var.usernames)
  user       = element(aws_iam_user.newusers.*.name, count.index)
  policy_arn = aws_iam_policy.iamreadonlyaccess.arn

# optional - if you don't generate the pwd from the terraform script comment the below resource
# generating login password for iam users
# resource "aws_iam_user_login_profile" "newusers" {
#   count                   = length(var.usernames)
#   user                    = element(aws_iam_user.newusers.*.name, count.index)
#   password_reset_required = false
#   # helps to generate the password
#   # output will be shown in the encrypted form
#   # reference link -
#   pgp_key = "some_encrypted_base64_encoded_string"
# }

2.6 Output File

The file returns the output values for the created resources. In this example, the output will return the ARN for the created users.

output "user_arn" {
  description = "user arn"
  value       = ["${aws_iam_user.newusers.*.arn}"]
# uncomment below if we are using the aws_iam_user_login_profile resource
# output "user_password" {
#   description = "console pwd in encrypted form. use keybase to decrypt it"
#   value       = ["${aws_iam_user_login_profile.newusers.*.encrypted_password}"]
# }

3. Code Run

Navigate to the project directory containing the above scripts and open the terminal. Execute the below commands in the respective order within the directory.


-- step1: initializing the new or existing terraform configuration --
terraform init

-- step2: generating the execution plan --
terraform plan

-- step3: building the infrastructure --
-- auto-approve flag skips interactive approval of the plan before applying
terraform apply --auto-approve

4. Demo

Once the terraform script is successfully executed head over the AWS console to confirm that the IAM structure is successful. Navigate to the policy section and we will see that the policy named – iamreadonlyaccess will be created.

IAM User terraform - created policy
Fig. 1: Terraform created policy

Now navigate to the user section and we will see that two users named – geek1 and geek2 will be created successfully.

IAM User terraform - created users
Fig. 2: Terraform created users

Open either of the users and navigate to the Permissions tab to confirm that the created policy is successfully attached to the user.

IAM User terraform - user attachment
Fig. 3: Policy-User attachment

That is all for this tutorial and I hope the article served you with whatever you were looking for. Happy Learning and do not forget to share!

5. Summary

In this tutorial, we learned about Terraform and created a simple module to create the two IAM users in the AWS portal and attach the IAM read-only policy to both users. You can download the source code from the Downloads section.

6. Download the Project

This was a tutorial on learning and implementing Terraform to create IAM User and policy on AWS.

You can download the full source code of this example here: How to create IAM User & Policy using Terraform on AWS


An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Inline Feedbacks
View all comments
Back to top button