Security As Code— Secure AWS Access Using Terraform Managed IAM Groups/Users
What Is AWS IAM?
AWS IAM stands for “Identity and Access Management”, it is a AWS web service that helps you securely control access to your AWS resources. When you first create an AWS account, you begin the root user and is accessed by signing in with the email address and password that you used to create the account. I strongly recommend you do not use root
user for your AWS tasks. Instead, you should use IAM Groups
to define different type/category of access, and assign IAM users
to each different groups.
IAM Group
Like any other groups, IAM Group
is just a collection of users. Groups let you specify permissions for multiple users, which can make it easier to manage the permissions for those users. It is important for you to create different groups for your organization, to best secure and manage your AWS resources.
Security as Code: Use Terraform for IAM Groups/Users Management
Created by HashiCorp, Terraform allows you to use Infrastructure as Code to provision and manage any cloud, infrastructure, or services. In this blog, I will show you how to use Terraform to create a IAM Group
and two IAM Users
, to control your application developers’ access to AWS resources.
Background
You have an application called “testapp”, it runs on EC2 instance and has data stored in AWS s3 buckets. As the app owner, you only want to grant developer accesses to the EC2 instance and s3 bucket.
Steps
- Create
iam_policy.tf
file
data "aws_iam_policy_document" "testapp_developer" {
# s3 full access
statement {
effect = "Allow"
actions = ["s3:*"]
resources = [
"arn:aws:s3:::${var.s3_bucket_name}",
"arn:aws:s3:::${var.s3_bucket_name}/*"
]
}
# EC2 restricted access
statement {
effect = "Allow"
actions = ["ec2:*"]
resources = ["arn:aws:ec2:${var.region}:${var.account}:instance/*"]
condition {
test = "StringLike"
values = ["testapp"]
variable = "ec2:ResourceTag/App"
}
}
}
resource "aws_iam_policy" "testapp_developer" {
name = "testapp_developer_policy"
description = "Policy for develop testapp"
policy = data.aws_iam_policy_document.testapp_developer.json
}
- Create
variables.tf
file, which defines all the variables
variable "account" {
default = "xxxxxxx" # Replace with your account ID
}
variable "region" {
default = "us-east-1"
}
variable "prefix" {
default = "testapp-prefix"
}
variable "s3_bucket_name" {
default = "testapp-bucket"
}
- Create
iam_groups.tf
file, which defines the group and users
provider "aws" {
profile = "profile" # Replace with your profile
region = "us-east-1"
}
resource "aws_iam_group" "testapp_developer" {
name = "TestappDeveloper"
}
resource "aws_iam_group_policy_attachment" "custom_policy" {
group = aws_iam_group.testapp_developer.name
policy_arn = aws_iam_policy.testapp_developer.arn
}
resource "aws_iam_group_membership" "developer" {
group = aws_iam_group.testapp_developer.name
name = "testapp-developers"
users = [
aws_iam_user.testapp_developer_user_one.name,
aws_iam_user.testapp_developer_user_two.name
]
}
resource "aws_iam_user" "testapp_developer_user_one" {
name = "testapp-dev1"
}
resource "aws_iam_user" "testapp_developer_user_two" {
name = "testapp-dev2"
}
Test and Run
- Initialize the terraform working directory
$ terraform init
- Rewrite all configuration files to a canonical format and style
$ terraform fmt
- Validate the syntax
$ terraform validate
Success! The configuration is valid.
- Actual deploy
$ terraform apply....
Plan: 6 to add, 0 to change, 0 to destroy.Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.Enter a value: yes
You can see once deployed, you will have a “TestappDeveloper” group in your AWS IAM
and two users created and assigned to this group.