AWS IAM groups and policies – Terraform

Let’s create a module to create and manage AWS IAM groups and policies with Terraform! In summary a Terraform module is one or more Terraform resources bundled together to be used a single Terraform resource. You can learn more about Terraform module’s here. If you have no idea what Terraform or Terragrunt then start here. Let’s code!

The Terraform module structure


The main file

The contains all the resources required to create AWS IAM groups and their policies. Notice this one uses three resources!

resource "aws_iam_group" "this" {
name = var.iam_group_name

resource "aws_iam_policy" "this" {
name = var.policy_name
description = var.policy_description
policy = var.policy

resource "aws_iam_group_policy_attachment" "this" {
group =
policy_arn = aws_iam_policy.this.arn

The vars file

variable iam_group_name {}

variable policy_name {}

variable policy_description {}

variable policy {}

Here’s the AWS IAM groups and policies Terraform module on GitHub:

Create AWS IAM groups and policies with Terraform

Let’s use the Terraform module to create one or many IAM groups and their policies! You can deploy with Terraform but I like to use Terragrunt.

The Terragrunt/Terraform structure

This is one way to create your deployment structure. You can name this directory anything you like.

├── dev
│   ├── inputs.yml
│   ├── terragrunt.hcl
│   └──
├── prod
│   └── terragrunt.hcl
│   ├── inputs.yml
│   └──
├── qa
│   └── terragrunt.hcl
│   ├── inputs.yml
│   └──
├── sec
│   └── terragrunt.hcl
│   ├── inputs.yml
│   └──
└── terragrunt.hcl

In this example we will be creating groups and policies for developers, cloud engineers, database admins, and network admins all with one and same Terraform module! Using a module will ensure consistency and governance for our AWS resources.

The Terraform files

I like to keep the main file clean. I mainly use it for data calls and local variables.

locals {
  account_id = data.aws_caller_identity.current.account_id

provider "aws" {
  region  = var.aws_region
  profile = var.aws_cli_profile

terraform {
  backend "s3" {}

data "aws_caller_identity" "current" {}

module "cloud_engineers" {
  source = ""

  iam_group_name     = "cloud-engineers"
  policy_name        = "cloud-engineers"
  policy_description = "Cloud Engineers policy"
  policy             = data.aws_iam_policy_document.cloud_engineers.json
# ......... etc. 

# Modules creates group and policy and attaches policy to group. 
module "network_admins" {
  source = ""

  iam_group_name     = "network-admins"
  policy_name        = "network-admins"
  policy_description = "Network Admins policy"
  policy             = data.aws_iam_policy_document.network_admins_main.json
# Create the network admins misc policy 
resource "aws_iam_policy" "network_admins_misc" {
  name        = "network-admins-misc"
  description = "Network Admins"
  policy      = data.aws_iam_policy_document.network_admins_misc.json
# Attach the above policy to the network admins group. 
resource "aws_iam_group_policy_attachment" "network_admins_misc" {
  group      = "network-admins"
  policy_arn = aws_iam_policy.network_admins_misc.arn

  depends_on = [aws_iam_policy.network_admins_misc]

The “cloud engineers” IAM policy file

data "aws_iam_policy_document" "cloud_engineers" {
  statement {
    sid    = "FullAccess"
    effect = "Allow"
    actions = [
    resources = ["*"]

To see the developers policy and more take a look at the complete code at

Now let’s apply the code by navigating to the desired environment directory. Then initiate with ‘terragrunt init’ and apply with ‘terragrunt apply’. More on Terragrunt initiation, plans and apply.

Subscribe to get notified when more AWS and Terraform code is published!



AWS IAM console groups
AWS IAM console: Groups
AWS IAM console group policies
AWS IAM Group policies