These examples demonstrate practical, real-world usage patterns for the access-policy module. Each example is self-contained and ready to run—simply copy the configuration, customize the values for your environment, and apply.

Getting Started

To run any example, follow these steps:

  1. Authenticate with the registry: terraform login registry.patterneddesigns.ca
  2. Initialize the working directory: terraform init
  3. Review the execution plan: terraform plan
  4. Apply the configuration: terraform apply

Usage Examples

Basic Usage

Minimal configuration for an IAM access policy

module "basic_policy" {
  source  = "registry.patterneddesigns.ca/governance/access-policy/aws"
  version = "2.1.0"

  policy_name = "basic-developer-access"
  policy_type = "iam"

  allowed_services = ["s3", "dynamodb", "lambda"]
}

S3 Read-Only Access

Read-only access to specific S3 buckets

module "s3_readonly_policy" {
  source  = "registry.patterneddesigns.ca/governance/access-policy/aws"
  version = "2.1.0"

  policy_name = "s3-readonly-access"
  policy_type = "iam"

  allowed_services = ["s3"]

  denied_actions = [
    "s3:PutObject",
    "s3:DeleteObject",
    "s3:PutBucketPolicy",
    "s3:DeleteBucket"
  ]

  resource_restrictions = {
    s3 = [
      "arn:aws:s3:::company-reports-*",
      "arn:aws:s3:::company-reports-*/*"
    ]
  }
}

# Attach to a role
resource "aws_iam_role_policy_attachment" "analyst" {
  role       = aws_iam_role.data_analyst.name
  policy_arn = module.s3_readonly_policy.policy_arn
}

EC2 Administrator

EC2 administrative access with security guardrails

module "ec2_admin_policy" {
  source  = "registry.patterneddesigns.ca/governance/access-policy/aws"
  version = "2.1.0"

  policy_name = "ec2-administrator"
  policy_type = "iam"

  allowed_services = [
    "ec2",
    "elasticloadbalancing",
    "autoscaling",
    "cloudwatch"
  ]

  denied_actions = [
    # Prevent VPC modifications
    "ec2:CreateVpc",
    "ec2:DeleteVpc",
    "ec2:ModifyVpcAttribute",
    # Prevent security group rule changes in production
    "ec2:AuthorizeSecurityGroupIngress",
    "ec2:RevokeSecurityGroupIngress",
    # Prevent large instance launches
    "ec2:RunInstances"
  ]

  resource_restrictions = {
    ec2 = [
      "arn:aws:ec2:*:*:instance/*",
      "arn:aws:ec2:*:*:volume/*"
    ]
  }
}

# Note: Additional instance type restrictions should be
# implemented via Service Control Policies

Cross-Account Access

Policy for cross-account resource access

module "cross_account_policy" {
  source  = "registry.patterneddesigns.ca/governance/access-policy/aws"
  version = "2.1.0"

  policy_name = "cross-account-data-access"
  policy_type = "iam"

  allowed_services = ["s3", "kms", "sts"]

  resource_restrictions = {
    s3 = [
      "arn:aws:s3:::shared-data-bucket-prod",
      "arn:aws:s3:::shared-data-bucket-prod/*"
    ]
    kms = [
      "arn:aws:kms:us-east-1:111122223333:key/shared-key-id"
    ]
    sts = [
      "arn:aws:iam::111122223333:role/DataAccessRole"
    ]
  }
}

# Role that can assume cross-account access
resource "aws_iam_role" "cross_account" {
  name = "cross-account-data-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = {
        AWS = "arn:aws:iam::444455556666:root"
      }
      Action = "sts:AssumeRole"
      Condition = {
        StringEquals = {
          "sts:ExternalId" = "secure-external-id"
        }
      }
    }]
  })
}

resource "aws_iam_role_policy_attachment" "cross_account" {
  role       = aws_iam_role.cross_account.name
  policy_arn = module.cross_account_policy.policy_arn
}

Least Privilege Pattern

Comprehensive least-privilege policy with explicit denies

module "least_privilege_policy" {
  source  = "registry.patterneddesigns.ca/governance/access-policy/aws"
  version = "2.1.0"

  policy_name = "application-service-policy"
  policy_type = "iam"

  # Only allow services the application actually needs
  allowed_services = [
    "s3",
    "dynamodb",
    "sqs",
    "sns",
    "logs",
    "xray"
  ]

  # Explicitly deny dangerous actions
  denied_actions = [
    # IAM escalation prevention
    "iam:*",
    "sts:AssumeRole",

    # Data exfiltration prevention
    "s3:GetBucketPolicy",
    "s3:PutBucketPolicy",
    "s3:DeleteBucket",

    # Infrastructure modification prevention
    "dynamodb:DeleteTable",
    "sqs:DeleteQueue",
    "sns:DeleteTopic",

    # Audit log tampering prevention
    "logs:DeleteLogGroup",
    "logs:DeleteLogStream"
  ]

  # Restrict to specific resources
  resource_restrictions = {
    s3 = [
      "arn:aws:s3:::myapp-data-${var.environment}/*"
    ]
    dynamodb = [
      "arn:aws:dynamodb:*:*:table/myapp-*"
    ]
    sqs = [
      "arn:aws:sqs:*:*:myapp-*"
    ]
    sns = [
      "arn:aws:sns:*:*:myapp-*"
    ]
  }
}

# Attach to application service role
resource "aws_iam_role_policy_attachment" "app_service" {
  role       = aws_iam_role.app_service.name
  policy_arn = module.least_privilege_policy.policy_arn
}