Migration Guide

Guide for migrating existing IAM infrastructure to be managed by the SEC Provisioner.

Table of Contents

Migrating from Manual IAM Setup

Step 1: Inventory Existing IAM Resources

Export your current IAM configuration:

# List existing groups
aws iam list-groups --query 'Groups[].GroupName' --output table

# List existing roles
aws iam list-roles --query 'Roles[?starts_with(RoleName, `your-prefix`)].RoleName' --output table

# Export group details
for group in $(aws iam list-groups --query 'Groups[].GroupName' --output text); do
  echo "=== $group ==="
  aws iam list-attached-group-policies --group-name $group
  aws iam list-group-policies --group-name $group
  aws iam get-group --group-name $group --query 'Users[].UserName'
done

# Export role details
for role in $(aws iam list-roles --query 'Roles[].RoleName' --output text | grep your-prefix); do
  echo "=== $role ==="
  aws iam get-role --role-name $role --query 'Role.AssumeRolePolicyDocument'
  aws iam list-attached-role-policies --role-name $role
done

Step 2: Map to SEC Configuration

Map your existing IAM resources to SEC Provisioner YAML:

Existing Resource

SEC Config Section

IAM Groups for team members

security.iam_groups

Service roles (SageMaker, Lambda, etc.)

security.service_roles

Cross-function assumable roles

security.assumable_roles

Cross-account roles

security.cross_account_roles

Managed policies

policy_assignments with levels

Example mapping:

# Existing: Group "data-science-team" with S3 read/write and SageMaker access
# Maps to:
security:
  iam_groups:
    data_scientists:
      description: Data scientists with ML model development access
      managed_policies:
        - CloudWatchLogsReadOnlyAccess
      policy_assignments:
        s3: level2          # read/write to project buckets
        sagemaker: level2   # dev endpoint access

Step 3: Choose Your Tier

Match your existing IAM complexity to a tier:

Your Current Setup

Recommended Tier

1-5 groups, basic roles

Startup-5

5-10 groups, governance roles, cross-account

Medium-10

10+ groups, FinOps, contractors, multi-account

Enterprise-12

Step 4: Document User-to-Group Mappings

Before migration, record which users belong to which groups:

# Export user-group mappings
for group in $(aws iam list-groups --query 'Groups[].GroupName' --output text); do
  users=$(aws iam get-group --group-name $group --query 'Users[].UserName' --output text)
  echo "$group: $users"
done > user-group-mappings.txt

Important: Save this file — you’ll need it to re-add users to the new groups after migration.

Step 5: Validate Configuration

docker run --rm \
  -v ~/.aws:/home/secuser/.aws:ro \
  -v $(pwd)/sec/configs:/app/configs:ro \
  -v $(pwd)/sec/reports:/app/reports \
  sec-provisioner:medium-10 \
  --config edge-prod-b001-us-west-1-sec.yaml \
  --action validate-config

Step 6: Export and Review

Review all resources before deployment:

# Export groups, roles, and policies
docker run --rm \
  -v ~/.aws:/home/secuser/.aws:ro \
  -v $(pwd)/sec/configs:/app/configs:ro \
  -v $(pwd)/sec/groups:/app/groups \
  -v $(pwd)/sec/reports:/app/reports \
  sec-provisioner:medium-10 \
  --config edge-prod-b001-us-west-1-sec.yaml \
  --action export-groups

docker run --rm \
  -v ~/.aws:/home/secuser/.aws:ro \
  -v $(pwd)/sec/configs:/app/configs:ro \
  -v $(pwd)/sec/roles:/app/roles \
  -v $(pwd)/sec/reports:/app/reports \
  sec-provisioner:medium-10 \
  --config edge-prod-b001-us-west-1-sec.yaml \
  --action export-roles

# Compare with existing setup
diff <(aws iam list-groups --query 'Groups[].GroupName' --output text | tr '\t' '\n' | sort) \
     <(ls sec/groups/ | sed 's/.*group-//;s/.json//' | sort)

Step 7: Test Deploy

Deploy with test suffix to verify without affecting existing resources:

docker run --rm \
  -v ~/.aws:/home/secuser/.aws:ro \
  -v $(pwd)/sec/configs:/app/configs:ro \
  -v $(pwd)/sec/reports:/app/reports \
  sec-provisioner:medium-10 \
  --config edge-prod-b001-us-west-1-sec.yaml \
  --action test-deploy

Verify the test resources in AWS Console, then delete:

aws cloudformation delete-stack --stack-name <test-stack-name> --region us-west-1

Step 8: Deploy Production

docker run --rm \
  -v ~/.aws:/home/secuser/.aws:ro \
  -v $(pwd)/sec/configs:/app/configs:ro \
  -v $(pwd)/sec/reports:/app/reports \
  sec-provisioner:medium-10 \
  --config edge-prod-b001-us-west-1-sec.yaml \
  --action deploy \
  --force

Step 9: Re-Add Users to New Groups

Using the mappings saved in Step 4:

# Re-add users to new groups
aws iam add-user-to-group --user-name jane.doe --group-name edge-prod-b001-group-data-scientists
aws iam add-user-to-group --user-name john.smith --group-name edge-prod-b001-group-ml-engineers
# ... repeat for all users

Step 10: Decommission Old IAM Resources

After all users are migrated and verified:

# Remove users from old groups first
aws iam remove-user-from-group --user-name jane.doe --group-name old-data-science-team

# Delete old inline policies
aws iam delete-group-policy --group-name old-data-science-team --policy-name old-policy

# Detach managed policies
aws iam detach-group-policy --group-name old-data-science-team \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

# Delete old groups
aws iam delete-group --group-name old-data-science-team

# Delete old roles (detach policies first)
aws iam delete-role --role-name old-sagemaker-role

Warning: Verify all users have been migrated before deleting old groups. Users will lose permissions immediately when removed from a group.

Migrating from Terraform

Step 1: Export Terraform State

terraform state list | grep "aws_iam"
terraform state show aws_iam_group.data_scientists
terraform state show aws_iam_role.sagemaker_execution
terraform state show aws_iam_policy.s3_access

Step 2: Map to SEC Configuration

Terraform Resource

SEC Config

aws_iam_group

security.iam_groups.<name>

aws_iam_role (service)

security.service_roles.<name>

aws_iam_role (assumable)

security.assumable_roles.<name>

aws_iam_policy

policy_assignments with matching level

aws_iam_group_membership

Manual user-to-group mapping (Step 9)

Step 3: Deploy and Migrate

Follow Steps 5-10 from the manual migration above.

Step 4: Remove from Terraform State

terraform state rm aws_iam_group.data_scientists
terraform state rm aws_iam_role.sagemaker_execution
terraform state rm aws_iam_policy.s3_access
# ... remove all IAM resources

Migrating from AWS CDK

Step 1: Review Synthesized Template

cdk synth > existing-template.yaml
grep "AWS::IAM" existing-template.yaml

Step 2: Map to SEC Configuration

Review the CloudFormation template and map IAM resources to SEC Provisioner YAML.

Step 3: Deploy and Migrate

Follow Steps 5-10 from the manual migration above.

Step 4: Destroy CDK Stack

cdk destroy

Tier Migration

Upgrading Tiers (e.g., Startup → Medium)

When your team grows and you need more groups and roles:

  1. Purchase the new tier via AWS Marketplace

  2. Create new configuration based on medium master config

  3. Migrate customizations from startup config (client, environment, deployment, tags)

  4. Delete startup stack:

    docker run --rm \
      -v ~/.aws:/home/secuser/.aws:ro \
      -v $(pwd)/sec/configs:/app/configs:ro \
      -v $(pwd)/sec/reports:/app/reports \
      sec-provisioner:startup-5 \
      --config edge-prod-b001-us-west-1-sec.yaml \
      --action delete-stack \
      --force
    
  5. Deploy medium stack:

    docker run --rm \
      -v ~/.aws:/home/secuser/.aws:ro \
      -v $(pwd)/sec/configs:/app/configs:ro \
      -v $(pwd)/sec/reports:/app/reports \
      sec-provisioner:medium-10 \
      --config edge-prod-b001-us-west-1-sec.yaml \
      --action deploy \
      --force
    
  6. Re-add users to the new groups (group names change with the new stack)

Note: There will be a brief period where users lose permissions between delete and deploy. Schedule during a maintenance window.

Downgrading Tiers

Downgrading removes groups and roles not available in the lower tier. Ensure no users depend on the removed groups before downgrading.

Rollback Procedures

CloudFormation Automatic Rollback

If deployment fails, CloudFormation automatically rolls back:

aws cloudformation describe-stack-events \
  --stack-name edge-prod-b001-us-west-1-medium-sec-stack \
  --query 'StackEvents[?ResourceStatus==`CREATE_FAILED`].[LogicalResourceId,ResourceStatusReason]' \
  --output table

Manual Rollback

If you need to revert after a successful deployment:

# Delete the new stack
docker run --rm \
  -v ~/.aws:/home/secuser/.aws:ro \
  -v $(pwd)/sec/configs:/app/configs:ro \
  -v $(pwd)/sec/reports:/app/reports \
  sec-provisioner:medium-10 \
  --config edge-prod-b001-us-west-1-sec.yaml \
  --action delete-stack \
  --force

If old IAM resources still exist, users can be re-added to old groups. If old resources were deleted, you’ll need to recreate them manually or redeploy with the SEC Provisioner.

User Access Rollback

If users lost access during migration:

  1. Re-add users to old groups (if they still exist)

  2. Or deploy SEC stack immediately to restore access

  3. Communicate with affected users about the timeline