Quickstart with IAM using CloudFormation¶
This guide covers CloudFormation deployment options for CredProxy, including IAM role setup, multi-SDK testing environments, and infrastructure as code for testing scenarios.
Overview¶
CloudFormation templates provide infrastructure as code for deploying CredProxy with proper IAM roles and configurations. This approach ensures:
Consistent Deployments: Repeatable infrastructure across environments
IAM Best Practices: Proper role-based access control
Multi-SDK Testing: Comprehensive testing across different AWS SDKs
Testing Ready: Security and scalability considerations for testing environments
Template Structure¶
The CloudFormation templates are located in the tooling/cloudformation/ directory:
credproxy-iam-role.yaml- Main IAM role template for CredProxygenerate-config.py- Configuration generator for multi-SDK testingdocker-compose.yaml- Generated Docker Compose configurationsocat.Dockerfile- Socat proxy sidecar container
Quick Start¶
Use the CloudFormation quickstart to create IAM roles and test CredProxy with multiple AWS SDKs:
# Set stack name (use this consistently)
export CREDPROXY_QS_STACK_NAME=credproxy-demo-role
# Deploy IAM Role
aws cloudformation deploy \
--template-file tooling/cloudformation/credproxy-iam-role.yaml \
--stack-name $CREDPROXY_QS_STACK_NAME \
--capabilities CAPABILITY_NAMED_IAM
# Generate config files
cd tooling/cloudformation
python3 generate-config.py ${CREDPROXY_QS_STACK_NAME}
# Start all SDK containers
docker compose up --force-recreate --remove-orphans --build
Result: Each SDK container will sequentially get AWS credentials through CredProxy with metrics collection enabled.
IAM Role Template¶
The credproxy-iam-role.yaml template creates the necessary IAM roles and policies for CredProxy operation.
Template Parameters¶
Parameters:
PathPrefix:
Type: String
Default: /credproxy/
Description: Path prefix for IAM roles
AllowedPattern: ^/.*[^/]$|^/$
RoleName:
Type: String
Default: credproxy-demo-role
Description: Name for the IAM role
AllowedPattern: [a-zA-Z0-9+=,.@_-]+
Resources Created¶
The template creates these AWS resources:
IAM Role: Main role for CredProxy with assume role policy
IAM Policy: Policy allowing STS AssumeRole and necessary AWS service access
CloudFormation Stack: Managed stack with all resources
Role Path Configuration¶
The template supports configurable role paths via the PathPrefix parameter:
Default:
/credproxy/- Creates roles under/credproxy/pathCustom: Any valid IAM role path (e.g.,
/myapp/,/testing/)Root:
/- Creates roles in root path (not recommended for testing environments)
Example with custom path:
aws cloudformation deploy \
--template-file tooling/cloudformation/credproxy-iam-role.yaml \
--stack-name my-credproxy-role \
--parameter-overrides PathPrefix=/myapp/ \
--capabilities CAPABILITY_NAMED_IAM
IAM Role Permissions¶
The IAM role includes these permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"sts:GetCallerIdentity",
"iam:GetUser",
"iam:GetRole"
],
"Resource": "*"
}
]
}
Multi-SDK Testing Setup¶
The CloudFormation template includes a comprehensive multi-SDK testing environment that validates CredProxy across different AWS SDKs.
Architecture¶
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ AWS CLI │ │ Python Boto3 │ │ Node.js SDK │
│ Container │───▶│ Container │───▶│ Container │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Go AWS SDK │ │ Socat Proxy │ │ CredProxy │
│ Container │───▶│ Sidecar │───▶│ Service │
└─────────────────┘ └─────────────────┘ └─────────────────┘
SDK Sequence¶
The testing setup follows this sequence:
aws-cli → Tests basic AWS CLI credential retrieval
python-boto3 → Tests Python boto3 SDK with credentials
node-aws-sdk → Tests Node.js AWS SDK v3
go-aws-sdk → Tests Go AWS SDK
Each SDK container:
Waits for CredProxy to be healthy
Uses its own auth token from
tokens/directoryGets AWS credentials with unique session name (
credproxy-{sdk}-session)Tests AWS API call (STS GetCallerIdentity)
Passes credentials to next SDK in sequence
Session Names: credproxy-aws-cli-session, credproxy-python-boto3-session,
credproxy-node-aws-sdk-session, credproxy-go-aws-sdk-session
Configuration Generation¶
The generate-config.py script creates the necessary configuration files:
python3 generate-config.py [stack_name]
Generated Files:
config.yaml - CredProxy configuration with AWS CLI service and metrics enabled
docker-compose.yaml - Multi-SDK containers with socat proxy sidecar
tokens/ - Directory with auth tokens for each SDK service
dynamic/ - Directory with individual SDK service configuration files
scripts/ - Directory with test scripts for each SDK
Example generated config.yaml:
aws_defaults:
region: ${fromEnv:AWS_DEFAULT_REGION}
server:
host: localhost
port: 1338
debug: false
credentials:
refresh_buffer_seconds: 300
retry_delay: 60
request_timeout: 30
metrics:
prometheus:
enabled: true
host: 0.0.0.0
port: 9090
dynamic_services:
enabled: true
directories:
- path: /credproxy/dynamic
include_patterns:
- .*\.yaml$
- .*\.yml$
exclude_patterns:
- ^\..*
- .*~$
- .*\.bak$
reload_interval: 5
services:
aws-cli:
auth_token: ${fromFile:/run/secrets/aws-cli-token}
source_credentials: {}
assumed_role:
RoleArn: arn:aws:iam::123456789012:role/credproxy/credproxy-role
RoleSessionName: credproxy-aws-cli-session
DurationSeconds: 3600
Dynamic Service Files¶
The SDK services (python-boto3, node-aws-sdk, go-aws-sdk) are configured as individual files in the dynamic/ directory. This allows for hot-reloading of service configurations without restarting CredProxy.
Example dynamic/python-boto3.yaml:
services:
python-boto3:
assumed_role:
RoleArn: arn:aws:iam::123456789012:role/credproxy/credproxy-role
RoleSessionName: credproxy-python-boto3-session
auth_token: ${fromFile:/run/secrets/python-boto3-token}
source_credentials: {}
Example dynamic/node-aws-sdk.yaml:
services:
node-aws-sdk:
assumed_role:
RoleArn: arn:aws:iam::123456789012:role/credproxy/credproxy-role
RoleSessionName: credproxy-node-aws-sdk-session
auth_token: ${fromFile:/run/secrets/node-aws-sdk-token}
source_credentials: {}
Example dynamic/go-aws-sdk.yaml:
services:
go-aws-sdk:
assumed_role:
RoleArn: arn:aws:iam::123456789012:role/credproxy/credproxy-role
RoleSessionName: credproxy-go-aws-sdk-session
auth_token: ${fromFile:/run/secrets/go-aws-sdk-token}
source_credentials: {}
Docker Compose Configuration¶
The generated Docker Compose configuration includes:
services:
credproxy:
image: public.ecr.aws/compose-x/aws/credproxy:latest
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
ports:
- 9090:9090
volumes:
- ./config.yaml:/credproxy/config.yaml:ro
- ./dynamic:/credproxy/dynamic:ro
- ~/.aws:/root/.aws:ro
user: 0:0
environment:
AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION:-eu-west-1}
AWS_PROFILE: ${AWS_PROFILE:-default}
CREDPROXY_CONFIG_FILE: /credproxy/config.yaml
CREDPROXY_LOG_FORMAT: json
CREDPROXY_LOG_LEVEL: info
healthcheck:
test:
- CMD
- /bin/lprobe
- -mode=http
- -port=1338
- -endpoint=/health
interval: 10s
timeout: 5s
retries: 3
start_period: 10s
secrets:
- aws-cli-token
- python-boto3-token
- node-aws-sdk-token
- go-aws-sdk-token
socat-proxy:
build:
context: .
dockerfile: ./dockerfiles/socat.Dockerfile
restart: unless-stopped
network_mode: service:credproxy
cap_add:
- NET_ADMIN
depends_on:
credproxy:
condition: service_healthy
aws-cli:
image: public.ecr.aws/aws-cli/aws-cli:latest
command:
- sts
- get-caller-identity
volumes:
- ./scripts:/scripts:ro
environment:
AWS_CONTAINER_CREDENTIALS_FULL_URI: http://localhost:1338/v1/credentials
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE: /run/secrets/aws-cli-token
AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION:-eu-west-1}
AWS_REGION: ${AWS_DEFAULT_REGION:-eu-west-1}
depends_on:
credproxy:
condition: service_healthy
secrets:
- aws-cli-token
network_mode: service:credproxy
python-boto3:
build:
context: .
dockerfile: ./dockerfiles/python-boto3.Dockerfile
volumes:
- ./scripts:/scripts:ro
environment:
AWS_CONTAINER_CREDENTIALS_FULL_URI: http://localhost:1338/v1/credentials
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE: /run/secrets/python-boto3-token
AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION:-eu-west-1}
AWS_REGION: ${AWS_DEFAULT_REGION:-eu-west-1}
depends_on:
credproxy:
condition: service_healthy
aws-cli:
condition: service_completed_successfully
secrets:
- python-boto3-token
network_mode: service:credproxy
node-aws-sdk:
build:
context: .
dockerfile: ./dockerfiles/node-aws-sdk.Dockerfile
environment:
AWS_CONTAINER_CREDENTIALS_FULL_URI: http://localhost:1338/v1/credentials
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE: /run/secrets/node-aws-sdk-token
AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION:-eu-west-1}
AWS_REGION: ${AWS_DEFAULT_REGION:-eu-west-1}
depends_on:
credproxy:
condition: service_healthy
aws-cli:
condition: service_completed_successfully
python-boto3:
condition: service_completed_successfully
secrets:
- node-aws-sdk-token
network_mode: service:credproxy
go-aws-sdk:
build:
context: .
dockerfile: ./dockerfiles/go-aws-sdk.Dockerfile
environment:
AWS_CONTAINER_CREDENTIALS_FULL_URI: http://localhost:1338/v1/credentials
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE: /run/secrets/go-aws-sdk-token
AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION:-eu-west-1}
AWS_REGION: ${AWS_DEFAULT_REGION:-eu-west-1}
depends_on:
credproxy:
condition: service_healthy
aws-cli:
condition: service_completed_successfully
python-boto3:
condition: service_completed_successfully
node-aws-sdk:
condition: service_completed_successfully
secrets:
- go-aws-sdk-token
network_mode: service:credproxy
secrets:
aws-cli-token:
file: ./tokens/aws-cli-token.txt
python-boto3-token:
file: ./tokens/python-boto3-token.txt
node-aws-sdk-token:
file: ./tokens/node-aws-sdk-token.txt
go-aws-sdk-token:
file: ./tokens/go-aws-sdk-token.txt
Metrics & Observability¶
The CloudFormation setup includes comprehensive metrics collection and monitoring.
Prometheus Metrics¶
# CredProxy API
curl http://localhost:1338/health
# Prometheus metrics
curl http://localhost:9090/metrics
Available Metrics:
credproxy_requests_total- Credential requests per service (success/error)credproxy_active_services- Number of active servicescredproxy_info- Application version information
Health Checks¶
Each service includes health checks:
healthcheck:
test:
- CMD
- /bin/lprobe
- -mode=http
- -port=1338
- -endpoint=/health
interval: 10s
timeout: 5s
retries: 3
start_period: 10s
Logging¶
Comprehensive logging for debugging and monitoring:
# View all logs
docker compose logs
# View specific service logs
docker compose logs credproxy
docker compose logs socat-proxy
docker compose logs aws-cli
# Follow logs in real-time
docker compose logs -f
Production Deployment¶
For enhanced testing scenarios, consider these additional CloudFormation configurations.
Enhanced Security¶
Resources:
CredProxyRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Ref RoleName
Path: !Ref PathPrefix
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
Action: sts:AssumeRole
Condition:
StringEquals:
aws:SourceArn: !Sub arn:aws:iam::${AWS::AccountId}:role/${PathPrefix}${RoleName}
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
Tags:
- Key: Environment
Value: testing
- Key: Application
Value: credproxy
- Key: Owner
Value: infrastructure
Multiple Environments¶
Deploy to multiple environments with different configurations:
# Development
aws cloudformation deploy \
--template-file tooling/cloudformation/credproxy-iam-role.yaml \
--stack-name credproxy-dev-role \
--parameter-overrides \
PathPrefix=/dev/ \
RoleName=credproxy-dev-role \
--capabilities CAPABILITY_NAMED_IAM
# Staging
aws cloudformation deploy \
--template-file tooling/cloudformation/credproxy-iam-role.yaml \
--stack-name credproxy-staging-role \
--parameter-overrides \
PathPrefix=/staging/ \
RoleName=credproxy-staging-role \
--capabilities CAPABILITY_NAMED_IAM
# Production
aws cloudformation deploy \
--template-file tooling/cloudformation/credproxy-iam-role.yaml \
--stack-name credproxy-prod-role \
--parameter-overrides \
PathPrefix=/prod/ \
RoleName=credproxy-prod-role \
--capabilities CAPABILITY_NAMED_IAM
Custom Resources¶
Extend the template with additional resources:
Resources:
# S3 bucket for logs
CredProxyLogsBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub credproxy-logs-${AWS::AccountId}
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
LifecycleConfiguration:
Rules:
- Id: DeleteOldLogs
Status: Enabled
ExpirationInDays: 30
# CloudWatch Log Group
CredProxyLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /credproxy/application
RetentionInDays: 14
# CloudWatch Alarms
CredProxyErrorAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: credproxy-error-rate
AlarmDescription: Alarm when CredProxy error rate is high
MetricName: credproxy_requests_total
Namespace: CredProxy
Statistic: Sum
Period: 300
EvaluationPeriods: 2
Threshold: 10
ComparisonOperator: GreaterThanThreshold
Dimensions:
- Name: status
Value: error
Advanced Configuration¶
Custom IAM Policies¶
Create custom IAM policies for specific use cases:
Resources:
CredProxyPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: credproxy-custom-policy
Roles:
- !Ref CredProxyRole
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
- sts:GetCallerIdentity
Resource: "*"
- Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
- s3:ListBucket
Resource: !Sub arn:aws:s3:::${CredProxyLogsBucket}/*
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/credproxy/*
Cross-Account Access¶
Configure cross-account role assumption:
Parameters:
TargetAccountId:
Type: String
Description: AWS Account ID for cross-account access
AllowedPattern: \d{12}
Resources:
CredProxyRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS: !Sub arn:aws:iam::${TargetAccountId}:root
Action: sts:AssumeRole
Condition:
StringEquals:
aws:SourceArn: !Sub arn:aws:iam::${TargetAccountId}:role/${PathPrefix}${RoleName}
Conditional Deployments¶
Use conditions for environment-specific configurations:
Parameters:
EnvironmentType:
Type: String
Default: dev
AllowedValues:
- dev
- staging
- prod
Conditions:
IsProduction: !Equals [!Ref EnvironmentType, prod]
IsDevelopment: !Equals [!Ref EnvironmentType, dev]
Resources:
CredProxyRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub credproxy-${EnvironmentType}-role
Path: !Sub /${EnvironmentType}/
# ... other properties ...
Tags:
- Key: Environment
Value: !Ref EnvironmentType
- Key: RequireMFA
Value: !If [IsProduction, "true", "false"]
Testing and Validation¶
After deployment, validate the setup:
# Test IAM role
aws sts get-caller-identity --role-arn arn:aws:iam::123456789012:role/credproxy-demo-role
# Test CredProxy health
curl http://localhost:1338/health
# Test credential retrieval
curl -H "Authorization: aws-cli-token" http://localhost:1338/v1/credentials
# Test metrics
curl http://localhost:9090/metrics
SDK Integration Tests¶
Run comprehensive tests across all SDKs:
# Start all containers
docker compose up --force-recreate --remove-orphans --build
# Watch the sequential execution
# Expected output:
# aws-cli: GetCallerIdentity successful
# python-boto3: GetCallerIdentity successful
# node-aws-sdk: GetCallerIdentity successful
# go-aws-sdk: GetCallerIdentity successful
Troubleshooting¶
Common Issues¶
CloudFormation Stack Creation Fails
Cause: Missing permissions or invalid parameters
Solution: - Verify AWS CLI credentials and permissions - Check parameter values are valid - Ensure CAPABILITY_NAMED_IAM is specified - Review CloudFormation stack events
IAM Role Not Found
Cause: Stack creation failed or role name mismatch
Solution: - Check stack status:
aws cloudformation describe-stacks- Verify role exists:aws iam get-role --role-name credproxy-demo-role- Re-deploy stack if needed
Container Startup Issues
Cause: Network or configuration problems
Solution: - Check Docker logs:
docker compose logs- Verify network connectivity - Validate configuration files - Check health check status
Credential Retrieval Fails
Cause: Token mismatch or IAM permission issues
Solution: - Verify tokens match between config and environment - Check IAM role permissions - Test role assumption manually - Review CredProxy logs
Debug Commands¶
# Check CloudFormation stack status
aws cloudformation describe-stacks --stack-name $CREDPROXY_QS_STACK_NAME
# Get IAM role details
aws iam get-role --role-name credproxy-demo-role
# Test role assumption
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/credproxy-demo-role --role-session-name test-session
# Check container status
docker compose ps
# View logs
docker compose logs credproxy
docker compose logs socat-proxy
# Test network connectivity
docker compose exec credproxy curl http://localhost:1338/health
# Check IP configuration
docker compose exec credproxy ip addr show
Cleanup¶
Remove deployed resources:
# Stop and remove containers
docker compose down
# Delete CloudFormation stack
aws cloudformation delete-stack --stack-name $CREDPROXY_QS_STACK_NAME
# Remove generated files
rm -rf tokens/ config.yaml docker-compose.yaml
# Clean up Docker images
docker image prune -f
# Verify stack deletion
aws cloudformation describe-stacks --stack-name $CREDPROXY_QS_STACK_NAME 2>/dev/null || echo "Stack deleted successfully"
Best Practices¶
Infrastructure as Code¶
Version Control: Store CloudFormation templates in version control
Parameterization: Use parameters for environment-specific values
Modular Design: Break down complex templates into nested stacks
Documentation: Document template parameters and outputs
Security¶
Least Privilege: Grant only necessary permissions
Resource Tagging: Tag all resources for cost allocation and management
Regular Rotation: Rotate access keys and credentials regularly
Audit Logging: Enable CloudTrail for all API calls
Monitoring¶
CloudWatch Alarms: Set up alarms for critical metrics
Log Aggregation: Centralize logs for analysis
Performance Monitoring: Monitor credential request latency and error rates
Cost Monitoring: Track AWS costs associated with CredProxy deployment
Maintenance¶
Regular Updates: Keep CloudFormation templates updated
Testing: Test template updates in separate testing environments
Backup: Backup configuration files and templates
Documentation: Keep documentation current with template changes
Next Steps¶
Docker Compose Deployment - Docker Compose deployment guide
Socat Proxy Sidecar for ECS Metadata - Socat proxy sidecar configuration
Configuration - Configuration options
Security Policy - Security best practices
Installation - Installation prerequisites