Secrets Rotation & Compliance Audit
AWS architecture template · Zero hardcoded credentials: EC2 fetches DB credentials from Secrets Manager with automatic 30-day rotation. CloudTrail captures every API call to an immutable S3 audit bucket.
Secrets Rotation & Compliance Audit is a free AWS architecture template built with CloudTrail, CloudWatch, EC2, IAM, KMS, Lambda, RDS, S3 and Secrets Manager. Open it in TheArchitect to edit the diagram, estimate monthly cost, and export the CloudFormation or Terraform that deploys it.
AWS services in this template
- CloudTrail
- CloudWatch
- EC2
- IAM
- KMS
- Lambda
- RDS
- S3
- Secrets Manager
Deployment notes
Needs input
- Set RDS endpoint in Secrets Manager rotation Lambda environment variable.
- Grant Secrets Manager permission to invoke the rotation Lambda.
- Create S3 bucket policy granting CloudTrail delivery access.
Generated CloudFormation — 9 resources
| Logical ID | Resource type |
|---|---|
| AppServerec2 | AWS::EC2::Instance |
| CustomerDBrds | AWS::RDS::DBInstance |
| DBCredentialssecretsmanager | AWS::SecretsManager::Secret |
| RotationFunctionlambda | AWS::Lambda::Function |
| DataCMKkms | AWS::KMS::Key |
| ComplianceTrailcloudtrail | AWS::CloudTrail::Trail |
| AuditBuckets3 | AWS::S3::Bucket |
| RotationFailureAlarmcloudwatch | AWS::CloudWatch::Alarm |
| RotationRoleiam | AWS::IAM::Role |
View the full CloudFormation template
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Generated by TheArchitect — https://www.thecloudarchitect.dev",
"Metadata": {
"TheArchitect": {
"Edges": [
{
"From": "AppServerec2",
"To": "CustomerDBrds",
"Label": "SQL over TLS"
},
{
"From": "RotationFunctionlambda",
"To": "CustomerDBrds",
"Label": "ALTER USER"
},
{
"From": "DataCMKkms",
"To": "DBCredentialssecretsmanager",
"Label": "encrypts secret"
},
{
"From": "DataCMKkms",
"To": "CustomerDBrds",
"Label": "encrypts storage"
},
{
"From": "ComplianceTrailcloudtrail",
"To": "AuditBuckets3",
"Label": "log delivery"
},
{
"From": "RotationFunctionlambda",
"To": "RotationFailureAlarmcloudwatch",
"Label": "error metric"
},
{
"From": "RotationRoleiam",
"To": "RotationFunctionlambda",
"Label": "execution role"
}
]
}
},
"Resources": {
"AppServerec2": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-0abcdef1234567890",
"InstanceType": "t3.small",
"DisableApiTermination": false
}
},
"CustomerDBrds": {
"Type": "AWS::RDS::DBInstance",
"Properties": {
"DBInstanceIdentifier": "compliance-db",
"Engine": "postgres",
"EngineVersion": "15.4",
"DBInstanceClass": "db.t3.medium",
"MultiAZ": false,
"AllocatedStorage": "20",
"StorageType": "gp3",
"StorageEncrypted": true,
"DeletionProtection": true,
"BackupRetentionPeriod": 7
}
},
"DBCredentialssecretsmanager": {
"Type": "AWS::SecretsManager::Secret",
"Properties": {
"Name": "compliance/db-credentials",
"Description": "RDS PostgreSQL credentials rotated every 30 days by rotation Lambda",
"GenerateSecretString": {
"PasswordLength": 32,
"ExcludeCharacters": "\"@/\\"
}
}
},
"RotationFunctionlambda": {
"Type": "AWS::Lambda::Function",
"DependsOn": [
"RotationRoleiam"
],
"Properties": {
"FunctionName": "db-credentials-rotation",
"Runtime": "python3.12",
"Handler": "rotation.handler",
"MemorySize": 256,
"Timeout": 120,
"Description": "Secrets Manager rotation function. Implements the four-step rotation: createSecret, setSecret (ALTER USER in RDS), testSecret, finishSecret.",
"Role": {
"Fn::GetAtt": [
"RotationRoleiam",
"Arn"
]
}
}
},
"DataCMKkms": {
"Type": "AWS::KMS::Key",
"Properties": {
"Description": "Data CMK — encrypts RDS storage and Secrets Manager secret value",
"EnableKeyRotation": true,
"Enabled": true,
"PendingWindowInDays": 30
}
},
"ComplianceTrailcloudtrail": {
"Type": "AWS::CloudTrail::Trail",
"Properties": {
"TrailName": "compliance-audit-trail",
"S3BucketName": "compliance-audit-logs",
"IsLogging": true,
"IsMultiRegionTrail": true,
"EnableLogFileValidation": true,
"IncludeGlobalServiceEvents": true
}
},
"AuditBuckets3": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": "compliance-audit-logs",
"VersioningConfiguration": {
"Status": "Enabled"
},
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"BlockPublicPolicy": true,
"IgnorePublicAcls": true,
"RestrictPublicBuckets": true
},
"ObjectLockEnabled": true,
"ObjectLockConfiguration": {
"ObjectLockEnabled": "Enabled"
}
}
},
"RotationFailureAlarmcloudwatch": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmName": "secrets-rotation-failure",
"AlarmDescription": "Rotation Lambda error — DB credentials may be stale. Investigate immediately.",
"Namespace": "AWS/Lambda",
"MetricName": "Errors",
"Statistic": "Sum",
"Period": 300,
"EvaluationPeriods": 1,
"Threshold": 1,
"ComparisonOperator": "GreaterThanOrEqualToThreshold",
"TreatMissingData": "notBreaching"
}
},
"RotationRoleiam": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "secrets-rotation-role",
"Description": "Lambda execution role for rotation function — SecretsManager + RDS describe + KMS",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
]
}
}
}
}Generated by TheArchitect from the diagram above. Review values such as names, CIDR ranges and instance sizes before deploying to your account.
Related templates
- Security BaselineSAA-C03: WAF + KMS + Secrets Manager + CloudTrail → S3 + CloudWatch + SNS
- Twitter/X Scale TestCloudFront behavior split, API Gateway VPC Link, public/internal ALBs, private app/data subnets, queues, media, and data stores
- CloudTrail AuditSAA-C03: CloudTrail multi-region logging → S3 + KMS + CloudWatch + SNS alerts