Use Terraform to manage AWS IAM Policies, Roles and Users
This blog post is going to be a comprehensive guide on managing the AWS IAM User, IAM Roles and IAM Policies using Terraform.
Managing IAM Users, Roles and Policies are always crucial from a security perspective. Proper management of the IAM User, IAM Roles and IAM Policies can really improve the operational burden as well as the security of the AWS environment.
In this blog post, we are going to use Terraform to manage the IAM User, IAM Roles and IAM Policies. There are a couple of examples we are going to take a look -
- Managing one IAM User, one IAM Roles and one IAM policies with terraform
- Managing one IAM user, two IAM Roles and two IAM policies with terraform
Table of Content
- Prerequisites
- Understanding IAM Roles and Policies
- Create an IAM User(aws_iam_user) - Alice
- Create an IAM Role(aws_iam_role) - alice_role
- Create IAM Policy(aws_iam_policy) - AllowS3Access
- Create IAM Role and Policy attachment
- Create an aws_s3_bucket
- Create AWS IAM Instance Profile (aws_iam_instance_profile) - AliceProfile
- Create IAM user(aws_iam_user) and IAM Policy(aws_iam_policy) attachment
- Attaching IAM Instance profile to EC2 instance
- Conclusion
1. Prerequisites
1. An active AWS account and a basic understanding of AWS services - Before you begin and start following the steps mentioned in this blog post, you must have an active AWS account.
If you are using AWS for the first time, then you can use their initial trial period credit, and you should be able to perform all the steps mentioned in this blog post.
2. Terraform is installed on your machine - This complete blog post is focused around setting up the IAM User, IAM Roles and IAM Policies using Terraform, so you must install Terraform CLI onto your working machine.
Please refer to this guide on - How to install Terraform
3. Familiarity with Terraform syntax (HCL) - This particular blog requires you to be familiar with Terraform. If this is the first time you are trying to learn the Terraform, then I would highly recommend building your understanding by following this tutorial series: - On getting started with Terraform
2. Understanding IAM Roles and Policies
Before we start writing Terraform code, it is really important to understand the concept of IAM roles and IAM policies.
1. IAM Roles - It is a set of permissions that can be performed on AWS resources such as EC2, S3 Bucket, etc. With the help of IAM Roles you can grant permission to -
- User
- AWS Services
Here are some benefits that you get with the IAM roles -
- Flexibility - The IAM roles can be assigned to any IAM user or AWS resource, and you can customize the granularity of the IAM roles based on your needs.
- Security - IAM roles are very granular in nature, and hence, they always add an extra layer of security to your cloud infrastructure.
- Scalability - When you use Terraform to manage IAM roles, it becomes really scalable, and any developer can manage the roles from the code.
2. IAM Policies - It is a JSON formatted document that defines the permissions for IAM users as well as IAM roles. With the help of IAM policies, you can control what kinds of actions you can perform on specific AWS resources.
Here are two types of policies that exist:
- Managed Policies - IAM policies are managed policies that are administered by the account administrator.
- Inline Policies - These policies are directly embedded in the IAM user, IAM group, and IAM roles.
3. Create an IAM User(aws_iam_user) - Alice
Let's start by creating an User which we call an IAM user. To keep our Terraform project code clean, I am going to create a file called iam-user.tf
and put the following code inside the file.
1# Step 1 : Create an IAM user named Alice
2
3resource "aws_iam_user" "alice" {
4name = "Alice"
5}
- The above code will create an IAM user named Alice.
- To run the above code, simply run terraform plan and terraform apply commands.
- After running the terraform code, you can verify the user by going into the AWS console -> IAM -> Access Management -> User create-iam-user.webp
4. Create an IAM Role(aws_iam_role) - alice_role
After creating the IAM user in the [Step-3][3], let's create an IAM Role. Here is the Terraform code for creating the IAM role -
1resource "aws_iam_role" "alice_role" {
2name = "AliceRole"
3assume_role_policy = jsonencode({
4Version = "2012-10-17"
5Statement = [
6{
7Action = "sts:AssumeRole"
8Effect = "Allow"
9Principal = {
10Service = "ec2.amazonaws.com"
11}
12}
13]
14})
15}
- The above code will create an IAM role named AliceRole.
- To run the above code, simply run terraform plan and terraform apply commands.
- After running the Terraform code, you can verify the user by going into the AWS console -> IAM -> Access Management -> Roles
- Click on the AliceRole to view the details about the roles .e.g., Creation Date, ARN, Instance Profile ARN etc..
- To view Permission Policy of the role click on the Permission and then click on the + icon to expand the policy permission.
Here is a detailed explanation of each policy:
- AliceRole - The name of the IAM role
- assume_role_policy - This is an attribute that sets the trust policy for the IAM role, which defines who can assume the role.
- Version = "2012-10-17": This line indicates the policy language version. In this case, it is the 2012-10-17 version.
- Statement = [...]: This is an array of policy statements. In this example, there's only one statement that is defined as follows:
- Action = "sts:AssumeRole": This specifies the action to be allowed, which is to assume the IAM role.
- Effect = "Allow": This indicates that the action is allowed.
- Principal = { ... }: This defines the principal (the entity that is allowed to assume the role). In this example, it is set to an AWS service.
- Service = "ec2.amazonaws.com": The service that is allowed to assume the role. In this case, it is the Amazon EC2 service.
5. Create IAM Policy(aws_iam_policy) - AllowS3Access
An AWS IAM policy is like a set of rules that decide who can do what in the digital world of AWS.
These rules help make sure that people or programs can only get to the things they need and can't touch anything they shouldn't.
Here is the IAM Policy for AllowS3Access -
1resource "aws_iam_policy" "allow_s3_access" {
2name = "AllowS3Access"
3description = "Allow Alice to access specific S3 resources"
4policy = jsonencode({
5Version = "2012-10-17"
6Statement = [
7{
8Action = [
9"s3:ListBucket",
10"s3:GetObject",
11"s3:PutObject"
12]
13Effect = "Allow"
14Resource = [
15"arn:aws:s3:::test-bucket-for-alice",
16"arn:aws:s3:::test-bucket-for-alice/*"
17]
18}
19]
20})
21}
Here is a detailed explanation of the above policy -
-
AllowS3Access - It is the name of the policy.
-
description - A meaningful description to tell more about the policy
-
policy - A Json string containing all the Actions and Resources
-
Version = "2012-10-17": This line indicates the policy language version. In this case, it is the 2012-10-17 version.
-
Statement = [...]: This is an array of policy statements. In this example, there's only one statement that is defined as follows:
-
Action = [...]: This lists the actions that are allowed by the policy. In this case, it includes:
-
"s3:ListBucket": Listing the contents of a bucket.
-
"s3:GetObject": Retrieving an object from the bucket.
-
"s3:PutObject": Uploading an object to the bucket.
-
Effect = "Allow": This indicates that the actions listed above are allowed by the policy.
-
Resource = [...]: This specifies the resources the policy applies to. In this example, there are two resources:
-
"arn:aws:s3:::test-bucket-for-alice": The Amazon Resource Name (ARN) of the S3 bucket is "test-bucket-for-alice". This allows the policy to apply to the bucket itself.
-
"arn:aws:s3:::test-bucket-for-alice/*": This allows the policy to apply to all objects within the "test-bucket-for-alice" bucket.
How to Create the Policy?
- To create the policy, run the above code: simply run terraform plan and terraform apply command
- After running the Terraform code, you can verify the user by going into the AWS console -> IAM -> Access Management -> Policies
- Click on the AllowS3Access Policy and you will find all the details related to that policy.
6. Create IAM Role and Policy attachment
Before we create the IAM Role and Policy attachment, let's try to understand Why it is important to attach the IAM Role and Policy in AWS?
IAM jobs and policy attachments are important in AWS because they help keep track of who can do what in a safe and controlled way. Here are some additional benefits that you will get with the IAM role and policy attachment:
1. Only necessary access: Only those who need to get in. It's like a school where only teachers have the keys to certain rooms. IAM roles and rules make sure that people or programs can only do what they are meant to do and nothing else. This makes sure that everything stays safe and sound.
2. One place to manage: Instead of writing down on a bunch of sticky notes who can do what, IAM jobs and policies let you keep track of everything in one place. This makes it easy to deal with rights and keep track of them.
3. Rules that can be used more than once: Imagine if you could make a rule like "All teachers can open classroom doors" and use it for every teacher in the school. You can make rules like this using IAM jobs and policies, so you don't have to say the same thing over and over again.
4. Easier to change: If the rules change, like letting some students into certain places, IAM roles and policies make it easy to change these rights. You don't have to go to each door and change the lock. Instead, you just have to change the rule in one place.
5. Safer sharing: Sometimes you have to let a friend take your video game or toy. IAM jobs and rules are like giving your friend the key to your locker so they can get your toy but not anything else. So, you can share access without thinking about someone going through your stuff.
Here is the IAM Role and Policy Attachment for the AliceRole and AllowS3Access policies:
1# IAM Role and IAM Policy Attachment
2
3resource "aws_iam_role_policy_attachment" "attach_s3_access" {
4policy_arn = aws_iam_policy.allow_s3_access.arn
5role = aws_iam_role.alice_role.name
6}
7. Create an aws_s3_bucket
In the previous 6 steps, we have created IAM User, IAM Role, IAM Policy and IAM RolePolicy Attachment but we haven't yet created an S3 Bucket.
Here is the Terraform code to create an S3 bucket:
1# S3 Bucket creation by the name - test-bucket-for-alice
2
3resource "aws_s3_bucket" "example" {
4bucket = "test-bucket-for-alice"
5
6tags = {
7Name = "test-bucket-for-alice"
8Environment = "Dev"
9}
10}
Apply the change by running the Terraform command-
- To create the S3 bucket, run the terraform plan and terraform apply commands.
- Here is the screenshot from my AWS Console after creating an S3 Bucket by the name - test-bucket-for-alice
8. Create AWS IAM Instance Profile (aws_iam_instance_profile) - AliceProfile
aws_iam_instance_profile is a Terraform resource used to create and manage an AWS IAM Instance Profile.
In the context of the current blog post, aws_iam_instance_profile is used to create an IAM Instance Profile that allows an Amazon EC2 instance to access the S3 bucket using the permissions defined in an IAM role.
Here is the Terraform code to create an AWS IAM instance profile:
1# AWS IAM Instance Profile - AliceProfile
2
3resource "aws_iam_instance_profile" "alice_profile" {
4name = "AliceProfile"
5role = aws_iam_role.alice_role.name
6}
To create an AWS IAM instance profile, run the above code: simply run terraform plan and terraform apply commands.
9. Create IAM user(aws_iam_user) and IAM Policy(aws_iam_policy) attachment
We have setup everything that is needed: IAM User, IAM Role and IAM Policy but we did not attach IAM User with IAM Policy yet.
Let's write the Terraform resource to attach the IAM User(aws_iam_user) with the IAM Policy(aws_iam_policy) -
1# Attaching the IAM user(aws_iam_user) to IAM Policy(aws_iam_policy)
2
3resource "aws_iam_user_policy_attachment" "alice_s3_access" {
4user = aws_iam_user.alice.name
5policy_arn = aws_iam_policy.allow_s3_access.arn
6}
Here is the screenshot I have taken from the AWS console, which shows all the permissions associated with the IAM User - Alice
10. Attaching IAM Instance profile to EC2 instance
Alright, so far we have covered a lot of topics and been able to create the following:
- IAM User : Alice
- IAM Role : AliceRole
- IAM Policy : AllowS3Access
- IAM Role Policy Attachment : AliceRole + AllowS3Access
- IAM Instance Profile : AliceProfile -> AliceRole
- IAM User Policy Attachment : Alice + AllowS3Access
Next Task - Let's bind the IAM Instance Profile to an EC2 instance, and we will do it the Terraform way, but let's take a peek into the AWS Console so that we know where to find these settings to attach the IAM Instance Profile option.
Here is the Terraform code to provision the EC2 instance as well as attach IAM Instance Profile -
(Note - Here is my GitHub Repository where you can find the complete project. If you are new to Terraform and want to learn more about it, then follow this post - How to Setup EC2 instance with Terraform)
1# Setup EC2 instance with iam_instance_profile
2
3resource "aws_instance" "ec2_example" {
4
5ami = "ami-0767046d1677be5a0"
6instance_type = "t2.micro"
7tags = {
8Name = "test-t2-micro"
9}
10key_name= "aws_key"
11vpc_security_group_ids = [aws_security_group.main.id]
12
13# Attach IAM instance profile with EC2 instance
14iam_instance_profile = aws_iam_instance_profile.alice_profile.name
15}
Here is the screenshot I have taken from my AWS console after provisioning the EC2 instance with aws_iam_instance_profile
11. Conclusion
I hope this blog post will help you get started with on How to manage the IAM Roles, IAM Policies and IAM User Permission with Terraform. All the steps mentioned in this blog are really necessary for setting up the correct IAM roles, IAM policies, and IAM permissions.
But the same steps can be customized to setup other IAM roles, IAM policies, and IAM User permissions as well.
If you have any questions or suggestions, then please put them in the comment section.
Posts in this Series
- Use Terraform to manage AWS IAM Policies, Roles and Users
- How to split Your Terraform main.tf File into Multiple Files
- How to use Terraform variable within variable
- Mastering the Terraform Lookup Function for Dynamic Keys
- Copy files to EC2 and S3 bucket using Terraform
- Troubleshooting Error creating EC2 Subnet InvalidSubnet Range The CIDR is Invalid
- Troubleshooting InvalidParameter Security group and subnet belong to different networks
- Managing strings in Terraform: A comprehensive guide
- How to use terraform depends_on meta argument?
- What is user_data in Terraform?
- Why you should not store terraform state file(.tfstate) inside Git Repository?
- How to import existing resource using terraform import comand?
- Terraform - A detailed guide on setting up ALB(Application Load Balancer) and SSL?
- Testing Infrastructure as Code with Terraform?
- How to remove a resource from Terraform state?
- What is Terraform null Resource?
- In terraform how to skip creation of resource if the resource already exist?
- How to setup Virtual machine on Google Cloud Platform
- How to use Terraform locals?
- Terraform Guide - Docker Containers & AWS ECR(elastic container registry)?
- How to generate SSH key in Terraform using tls_private_key?
- How to fix-Terraform Error acquiring the state lock ConditionalCheckFiledException?
- Terraform Template - A complete guide?
- How to use Terragrunt?
- Terraform and AWS Multi account Setup?
- Terraform and AWS credentials handling?
- How to fix-error configuring S3 Backend no valid credential sources for S3 Backend found?
- Terraform state locking using DynamoDB (aws_dynamodb_table)?
- Managing Terraform states?
- Securing AWS secrets using HashiCorp Vault with Terraform?
- How to use Workspaces in Terraform?
- How to run specific terraform resource, module, target?
- How Terraform modules works?
- Secure AWS EC2s & GCP VMs with Terraform SSH Keys!
- What is terraform provisioner?
- Is terraform destroy needed before terraform apply?
- How to fix terraform error Your query returned no results. Please change your search criteria and try again?
- How to use Terraform Data sources?
- How to use Terraform resource meta arguments?
- How to use Terraform Dynamic blocks?
- Terraform - How to nuke AWS resources and save additional AWS infrastructure cost?
- Understanding terraform count, for_each and for loop?
- How to use Terraform output values?
- How to fix error configuring Terraform AWS Provider error validating provider credentials error calling sts GetCallerIdentity SignatureDoesNotMatch?
- How to fix Invalid function argument on line in provider credentials file google Invalid value for path parameter no file exists
- How to fix error value for undeclared variable a variable named was assigned on the command line?
- What is variable.tf and terraform.tfvars?
- How to use Terraform Variables - Locals,Input,Output
- Terraform create EC2 Instance on AWS
- How to fix Error creating service account googleapi Error 403 Identity and Access Management (IAM) API has not been used in project before or it is disabled
- Install terraform on Ubuntu 20.04, CentOS 8, MacOS, Windows 10, Fedora 33, Red hat 8 and Solaris 11