IAM Permissions

Overview

Table of Contents

The VPC Provisioner requires specific IAM permissions to create and manage VPC infrastructure via CloudFormation. This guide provides the minimum required permissions and best practices for security.

Quick Start - Generate IAM Policy

The VPC Provisioner can generate an IAM policy file tailored to your configuration:

docker run --rm \
  -v $(pwd)/vpc/configs:/app/configs:ro \
  -v $(pwd)/vpc/policies:/app/policies \
  -v $(pwd)/vpc/reports:/app/reports \
  vpc-provisioner:latest \
  --config edge-prod-a001-us-west-2-vpc.yaml \
  --action create-policy

Output: mlops-infra-suite/vpc/policies/<config-name>-vpc-iam-policy.json

This generated policy includes all required permissions scoped to your company prefix and AWS account.


Minimum Required Permissions

Complete IAM Policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EC2VPCManagement",
      "Effect": "Allow",
      "Action": [
        "ec2:CreateVpc",
        "ec2:DeleteVpc",
        "ec2:DescribeVpcs",
        "ec2:DescribeSubnets",
        "ec2:DescribeRouteTables",
        "ec2:DescribeInternetGateways",
        "ec2:DescribeNatGateways",
        "ec2:DescribeAddresses",
        "ec2:CreateSubnet",
        "ec2:DeleteSubnet",
        "ec2:CreateRouteTable",
        "ec2:DeleteRouteTable",
        "ec2:AssociateRouteTable",
        "ec2:DisassociateRouteTable",
        "ec2:CreateInternetGateway",
        "ec2:AttachInternetGateway",
        "ec2:DetachInternetGateway",
        "ec2:DeleteInternetGateway",
        "ec2:CreateNatGateway",
        "ec2:DeleteNatGateway",
        "ec2:AllocateAddress",
        "ec2:ReleaseAddress",
        "ec2:CreateRoute",
        "ec2:DeleteRoute",
        "ec2:CreateTags",
        "ec2:DeleteTags",
        "ec2:ModifyVpcAttribute"
      ],
      "Resource": "*"
    },
    {
      "Sid": "CloudFormationManagement",
      "Effect": "Allow",
      "Action": [
        "cloudformation:CreateStack",
        "cloudformation:DeleteStack",
        "cloudformation:DescribeStacks",
        "cloudformation:UpdateStack",
        "cloudformation:ValidateTemplate",
        "cloudformation:DescribeStackEvents",
        "cloudformation:DescribeStackResources"
      ],
      "Resource": "arn:aws:cloudformation:*:*:stack/*/*"
    },
    {
      "Sid": "S3TemplateAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::*-*/templates/*"
    },
    {
      "Sid": "S3BucketList",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::*"
    }
  ]
}

Permissions by Action

Actions Requiring No AWS Permissions

These actions only validate or generate files locally:

  • validate-config - Validates YAML against schema

  • create-policy - Generates IAM policy JSON file

  • create-prov-template - Generates CloudFormation template

  • validate-prov-template - Validates generated template locally (YAML syntax, structure, reference integrity)

Required: None (no AWS API calls)


Actions Requiring AWS Permissions

create-vpc

Creates VPC infrastructure via CloudFormation stack.

Required Permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:CreateStack",
        "cloudformation:DescribeStacks",
        "cloudformation:DescribeStackEvents",
        "ec2:CreateVpc",
        "ec2:CreateSubnet",
        "ec2:CreateRouteTable",
        "ec2:CreateInternetGateway",
        "ec2:CreateNatGateway",
        "ec2:AllocateAddress",
        "ec2:AttachInternetGateway",
        "ec2:AssociateRouteTable",
        "ec2:CreateRoute",
        "ec2:CreateTags",
        "ec2:ModifyVpcAttribute"
      ],
      "Resource": "*"
    }
  ]
}

delete-vpc

Deletes VPC infrastructure by deleting CloudFormation stack.

Required Permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:DeleteStack",
        "cloudformation:DescribeStacks",
        "cloudformation:DescribeStackEvents",
        "ec2:DeleteVpc",
        "ec2:DeleteSubnet",
        "ec2:DeleteRouteTable",
        "ec2:DeleteInternetGateway",
        "ec2:DeleteNatGateway",
        "ec2:ReleaseAddress",
        "ec2:DetachInternetGateway",
        "ec2:DisassociateRouteTable",
        "ec2:DeleteRoute",
        "ec2:DeleteTags",
        "ec2:DescribeVpcs",
        "ec2:DescribeSubnets",
        "ec2:DescribeRouteTables",
        "ec2:DescribeInternetGateways",
        "ec2:DescribeNatGateways",
        "ec2:DescribeAddresses"
      ],
      "Resource": "*"
    }
  ]
}

Permission Scoping Best Practices

1. Scope by Company Prefix

Limit S3 permissions to buckets matching your company prefix:

{
  "Resource": "arn:aws:s3:::edge-*/templates/*"
}

2. Scope by AWS Account

Limit CloudFormation permissions to your account:

{
  "Resource": "arn:aws:cloudformation:us-west-2:123456789012:stack/*/*"
}

3. Scope by Region

Limit EC2 permissions to specific regions:

{
  "Resource": "arn:aws:ec2:us-west-2:123456789012:*"
}

4. Scope by Environment

Create separate IAM policies for dev, staging, prod:

{
  "Condition": {
    "StringLike": {
      "aws:RequestTag/Environment": "production"
    }
  }
}

IAM Policy Examples

Read-Only Access (Validation Only)

For users who only validate configurations:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeVpcs",
        "ec2:DescribeSubnets",
        "ec2:DescribeRouteTables",
        "ec2:DescribeInternetGateways",
        "ec2:DescribeNatGateways",
        "cloudformation:DescribeStacks",
        "cloudformation:DescribeStackResources"
      ],
      "Resource": "*"
    }
  ]
}

Development Environment

For dev/test environments with limited scope:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:*",
        "cloudformation:*"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": "us-west-2"
        }
      }
    }
  ]
}

Production Environment

For production with strict scoping:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EC2VPCProd",
      "Effect": "Allow",
      "Action": [
        "ec2:CreateVpc",
        "ec2:DeleteVpc",
        "ec2:DescribeVpcs",
        "ec2:CreateSubnet",
        "ec2:DeleteSubnet",
        "ec2:CreateRouteTable",
        "ec2:DeleteRouteTable",
        "ec2:CreateInternetGateway",
        "ec2:DeleteInternetGateway",
        "ec2:CreateNatGateway",
        "ec2:DeleteNatGateway",
        "ec2:AllocateAddress",
        "ec2:ReleaseAddress",
        "ec2:CreateTags"
      ],
      "Resource": "arn:aws:ec2:us-west-2:123456789012:*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/Environment": "production"
        }
      }
    },
    {
      "Sid": "CloudFormationProd",
      "Effect": "Allow",
      "Action": [
        "cloudformation:CreateStack",
        "cloudformation:DeleteStack",
        "cloudformation:DescribeStacks",
        "cloudformation:DescribeStackEvents"
      ],
      "Resource": "arn:aws:cloudformation:us-west-2:123456789012:stack/edge-prod-*/*"
    }
  ]
}

IAM Role for EC2/ECS

Trust Policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Permissions Policy

Attach the complete IAM policy (see above) to this role.


IAM User Setup

Create IAM User

aws iam create-user --user-name vpc-provisioner-user

Attach Policy

# Create policy
aws iam create-policy \
  --policy-name VpcProvisionerPolicy \
  --policy-document file://policies/edge-prod-a001-us-west-2-vpc-iam-policy.json

# Attach to user
aws iam attach-user-policy \
  --user-name vpc-provisioner-user \
  --policy-arn arn:aws:iam::123456789012:policy/VpcProvisionerPolicy

Create Access Keys

aws iam create-access-key --user-name vpc-provisioner-user

Additional Permissions for Optional Features

NAT Gateway

NAT Gateway requires Elastic IP allocation:

{
  "Effect": "Allow",
  "Action": [
    "ec2:AllocateAddress",
    "ec2:ReleaseAddress",
    "ec2:DescribeAddresses",
    "ec2:CreateNatGateway",
    "ec2:DeleteNatGateway",
    "ec2:DescribeNatGateways"
  ],
  "Resource": "*"
}

VPC Peering (Future Feature)

If VPC peering is added:

{
  "Effect": "Allow",
  "Action": [
    "ec2:CreateVpcPeeringConnection",
    "ec2:AcceptVpcPeeringConnection",
    "ec2:DeleteVpcPeeringConnection",
    "ec2:DescribeVpcPeeringConnections"
  ],
  "Resource": "*"
}

Security Best Practices

1. Principle of Least Privilege

Grant only permissions needed for specific actions. Use the generated IAM policy as a starting point.

2. Use Resource Restrictions

Always scope permissions to specific resources when possible:

{
  "Resource": "arn:aws:ec2:us-west-2:123456789012:vpc/*"
}

3. Use Condition Keys

Add conditions for additional security:

{
  "Condition": {
    "StringEquals": {
      "aws:RequestedRegion": "us-west-2"
    }
  }
}

4. Separate Roles by Environment

  • vpc-provisioner-dev-role - Development

  • vpc-provisioner-staging-role - Staging

  • vpc-provisioner-prod-role - Production

5. Enable MFA for Sensitive Operations

{
  "Condition": {
    "Bool": {
      "aws:MultiFactorAuthPresent": "true"
    }
  }
}

6. Rotate Credentials Regularly

  • Rotate access keys every 90 days

  • Use temporary credentials when possible

  • Audit credential usage with CloudTrail

7. Monitor IAM Activity

# Enable CloudTrail
aws cloudtrail create-trail \
  --name vpc-provisioner-audit \
  --s3-bucket-name audit-logs-bucket

# Start logging
aws cloudtrail start-logging --name vpc-provisioner-audit

Troubleshooting Permission Issues

Access Denied Errors

# Check current user/role
aws sts get-caller-identity

# Test specific permission
aws ec2 describe-vpcs --region us-west-2

Policy Simulator

Use AWS Policy Simulator to test permissions: https://policysim.aws.amazon.com/

CloudTrail Logs

Check CloudTrail for denied API calls:

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=CreateVpc \
  --max-results 10

Permission Summary by Action

Action

CloudFormation

EC2

S3

validate-config

create-policy

create-prov-template

validate-prov-template

show-changes

check-drift

test-deploy

✅*

create-vpc

✅*

delete-vpc

*Only if storing templates in S3


EC2 Permissions Breakdown

VPC Operations

  • ec2:CreateVpc - Create VPC

  • ec2:DeleteVpc - Delete VPC

  • ec2:DescribeVpcs - List/describe VPCs

  • ec2:ModifyVpcAttribute - Enable DNS support/hostnames

Subnet Operations

  • ec2:CreateSubnet - Create subnets

  • ec2:DeleteSubnet - Delete subnets

  • ec2:DescribeSubnets - List/describe subnets

Route Table Operations

  • ec2:CreateRouteTable - Create route tables

  • ec2:DeleteRouteTable - Delete route tables

  • ec2:DescribeRouteTables - List/describe route tables

  • ec2:AssociateRouteTable - Associate route table with subnet

  • ec2:DisassociateRouteTable - Disassociate route table

  • ec2:CreateRoute - Create routes

  • ec2:DeleteRoute - Delete routes

Internet Gateway Operations

  • ec2:CreateInternetGateway - Create IGW

  • ec2:DeleteInternetGateway - Delete IGW

  • ec2:DescribeInternetGateways - List/describe IGWs

  • ec2:AttachInternetGateway - Attach IGW to VPC

  • ec2:DetachInternetGateway - Detach IGW from VPC

NAT Gateway Operations

  • ec2:CreateNatGateway - Create NAT Gateway

  • ec2:DeleteNatGateway - Delete NAT Gateway

  • ec2:DescribeNatGateways - List/describe NAT Gateways

  • ec2:AllocateAddress - Allocate Elastic IP for NAT

  • ec2:ReleaseAddress - Release Elastic IP

  • ec2:DescribeAddresses - List/describe Elastic IPs

Tagging Operations

  • ec2:CreateTags - Add tags to resources

  • ec2:DeleteTags - Remove tags from resources


CloudFormation Permissions Breakdown

  • cloudformation:CreateStack - Create CloudFormation stack

  • cloudformation:DeleteStack - Delete CloudFormation stack

  • cloudformation:DescribeStacks - Get stack status

  • cloudformation:UpdateStack - Update existing stack

  • cloudformation:ValidateTemplate - Validate template syntax

  • cloudformation:DescribeStackEvents - Get stack events/logs

  • cloudformation:DescribeStackResources - List stack resources


S3 Permissions Breakdown

  • s3:GetObject - Read CloudFormation templates

  • s3:PutObject - Upload CloudFormation templates

  • s3:DeleteObject - Delete CloudFormation templates

  • s3:ListBucket - List bucket contents

Note: S3 permissions are optional and only needed if storing templates in S3.


Cost Considerations

NAT Gateway Permissions

NAT Gateways incur hourly charges plus data transfer costs:

  • Single NAT Gateway: ~$32/month + data transfer

  • High Availability (3 AZs): ~$96/month + data transfer

Ensure proper cost allocation tags are applied.


Additional Resources

  • AWS IAM Best Practices: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html

  • VPC Security Best Practices: https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-best-practices.html

  • IAM Policy Simulator: https://policysim.aws.amazon.com/

  • CloudFormation Permissions: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html