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- Developmentvpc-provisioner-staging-role- Stagingvpc-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 VPCec2:DeleteVpc- Delete VPCec2:DescribeVpcs- List/describe VPCsec2:ModifyVpcAttribute- Enable DNS support/hostnames
Subnet Operations¶
ec2:CreateSubnet- Create subnetsec2:DeleteSubnet- Delete subnetsec2:DescribeSubnets- List/describe subnets
Route Table Operations¶
ec2:CreateRouteTable- Create route tablesec2:DeleteRouteTable- Delete route tablesec2:DescribeRouteTables- List/describe route tablesec2:AssociateRouteTable- Associate route table with subnetec2:DisassociateRouteTable- Disassociate route tableec2:CreateRoute- Create routesec2:DeleteRoute- Delete routes
Internet Gateway Operations¶
ec2:CreateInternetGateway- Create IGWec2:DeleteInternetGateway- Delete IGWec2:DescribeInternetGateways- List/describe IGWsec2:AttachInternetGateway- Attach IGW to VPCec2:DetachInternetGateway- Detach IGW from VPC
NAT Gateway Operations¶
ec2:CreateNatGateway- Create NAT Gatewayec2:DeleteNatGateway- Delete NAT Gatewayec2:DescribeNatGateways- List/describe NAT Gatewaysec2:AllocateAddress- Allocate Elastic IP for NATec2:ReleaseAddress- Release Elastic IPec2:DescribeAddresses- List/describe Elastic IPs
Tagging Operations¶
ec2:CreateTags- Add tags to resourcesec2:DeleteTags- Remove tags from resources
CloudFormation Permissions Breakdown¶
cloudformation:CreateStack- Create CloudFormation stackcloudformation:DeleteStack- Delete CloudFormation stackcloudformation:DescribeStacks- Get stack statuscloudformation:UpdateStack- Update existing stackcloudformation:ValidateTemplate- Validate template syntaxcloudformation:DescribeStackEvents- Get stack events/logscloudformation:DescribeStackResources- List stack resources
S3 Permissions Breakdown¶
s3:GetObject- Read CloudFormation templatess3:PutObject- Upload CloudFormation templatess3:DeleteObject- Delete CloudFormation templatess3: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