aws-cloudformation-security

安装量: 72
排名: #10695

安装

npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill aws-cloudformation-security
AWS CloudFormation Security
Overview
Create secure AWS infrastructure using CloudFormation templates with security best practices. This skill covers encryption with AWS KMS, secrets management with Secrets Manager, secure parameters, IAM least privilege, security groups, TLS/SSL certificates, and defense-in-depth strategies.
When to Use
Use this skill when:
Creating CloudFormation templates with encryption at-rest and in-transit
Managing secrets and credentials with AWS Secrets Manager
Configuring AWS KMS for encryption keys
Implementing secure parameters with SSM Parameter Store
Creating IAM policies with least privilege
Configuring security groups and network security
Implementing secure cross-stack references
Configuring TLS/SSL for AWS services
Applying defense-in-depth for infrastructure
Instructions
Follow these steps to create secure CloudFormation infrastructure:
Define Encryption Keys
Create KMS keys for data encryption
Set Up Secrets
Use Secrets Manager for credentials and API keys
Configure Secure Parameters
Use SSM Parameter Store with encryption
Implement IAM Policies
Apply least privilege principles
Create Security Groups
Configure network access controls
Set Up TLS Certificates
Use ACM for SSL/TLS certificates
Enable Encryption
Configure encryption for storage and transit
Implement Monitoring
Enable CloudTrail and security logging For complete examples, see the EXAMPLES.md file. Examples The following examples demonstrate common security patterns: Example 1: KMS Key for Encryption KmsKey : Type : AWS : : KMS : : Key Properties : KeyPolicy : Version : "2012-10-17" Statement : - Effect : Allow Principal : AWS : !Sub "arn:aws:iam::${AWS::AccountId}:root" Action : kms : * Resource : "" - Effect : Allow Principal : Service : s3.amazonaws.com Action : - kms : Encrypt - kms : Decrypt Resource : "" KmsAlias : Type : AWS : : KMS : : Alias Properties : AliasName : !Sub "alias/${AWS::StackName}-key" TargetKeyId : !Ref KmsKey Example 2: Secrets Manager Secret DatabaseSecret : Type : AWS : : SecretsManager : : Secret Properties : Name : !Sub "${AWS::StackName}/database-credentials" Description : Database credentials for application SecretString : !Sub | { "username": "${DBUsername}", "password": "${DBPassword}", "host": "${DBInstance.Endpoint.Address}", "port": "${DBInstance.Endpoint.Port}" } Example 3: Secure Parameter SecureParameter : Type : AWS : : SSM : : Parameter Properties : Name : !Sub "/${AWS::StackName}/api-key" Type : SecureString Value : !Ref ApiKeyValue Description : Secure API key for external service For complete production-ready examples, see EXAMPLES.md . CloudFormation Template Structure Base Template with Security Section AWSTemplateFormatVersion : 2010-09-09 Description : Secure infrastructure template with encryption and secrets management Metadata : AWS::CloudFormation::Interface : ParameterGroups : - Label : default : Encryption Settings Parameters : - EncryptionKeyArn - SecretsKmsKeyId - Label : default : Security Configuration Parameters : - SecurityLevel - EnableVPCPeering Parameters : Environment : Type : String Default : dev AllowedValues : - dev - staging - production EncryptionKeyArn : Type : AWS : : KMS : : Key : : Arn Description : KMS key ARN for encryption SecretsKmsKeyId : Type : String Description : KMS key ID for secrets encryption Mappings : SecurityConfig : dev : EnableDetailedMonitoring : false RequireMultiAZ : false staging : EnableDetailedMonitoring : true RequireMultiAZ : false production : EnableDetailedMonitoring : true RequireMultiAZ : true Conditions : IsProduction : !Equals [ !Ref Environment , production ] EnableEnhancedMonitoring : !Equals [ !Ref Environment , production ] Resources :

Resources will be defined here

Outputs : SecurityConfigurationOutput : Description : Security configuration applied Value : !Ref Environment AWS KMS - Encryption Complete KMS Key with Full Policy Resources :

Master KMS Key for application

ApplicationKmsKey : Type : AWS : : KMS : : Key Properties : Description : "KMS Key for application encryption" KeyPolicy : Version : "2012-10-17" Id : "application-key-policy" Statement :

Allow key management to administrators

- Sid : "EnableIAMPolicies" Effect : Allow Principal : AWS : !Sub "arn:aws:iam::${AWS::AccountId}:role/AdminRole" Action : - kms : Create - kms : Describe - kms : Enable - kms : List - kms : Put - kms : Update - kms : Revoke - kms : Disable - kms : Get - kms : Delete - kms : TagResource - kms : UntagResource Resource : "*" Condition : StringEquals : aws:PrincipalOrgID : !Ref OrganizationId

Allow encryption/decryption for application roles

- Sid : "AllowCryptographicOperations" Effect : Allow Principal : AWS : - !Sub "arn:aws:iam::${AWS::AccountId}:role/LambdaExecutionRole" - !Sub "arn:aws:iam::${AWS::AccountId}:role/ECSTaskRole" Action : - kms : Encrypt - kms : Decrypt - kms : GenerateDataKey - kms : ReEncrypt Resource : "*"

Allow key usage for specific services

- Sid : "AllowKeyUsageForSpecificServices" Effect : Allow Principal : Service : - lambda.amazonaws.com - ecs.amazonaws.com - rds.amazonaws.com Action : - kms : Encrypt - kms : Decrypt - kms : GenerateDataKey Resource : "" KeyUsage : ENCRYPT_DECRYPT EnableKeyRotation : true PendingWindowInDays : 30

Alias for the key

ApplicationKmsKeyAlias : Type : AWS : : KMS : : Alias Properties : AliasName : !Sub "alias/application-${Environment}" TargetKeyId : !Ref ApplicationKmsKey

KMS Key for S3 bucket encryption

S3KmsKey : Type : AWS : : KMS : : Key Properties : Description : "KMS Key for S3 bucket encryption" KeyPolicy : Version : "2012-10-17" Statement : - Sid : "AllowS3Encryption" Effect : Allow Principal : Service : s3.amazonaws.com Action : - kms : Encrypt - kms : Decrypt - kms : GenerateDataKey Resource : "" Condition : StringEquals : aws:SourceAccount : !Ref AWS : : AccountId

KMS Key for RDS encryption

RdsKmsKey : Type : AWS : : KMS : : Key Properties : Description : "KMS Key for RDS database encryption" KeyPolicy : Version : "2012-10-17" Statement : - Sid : "AllowRDSEncryption" Effect : Allow Principal : Service : rds.amazonaws.com Action : - kms : Encrypt - kms : Decrypt - kms : GenerateDataKey Resource : "" S3 Bucket with KMS Encryption Resources : EncryptedS3Bucket : Type : AWS : : S3 : : Bucket Properties : BucketName : !Sub "secure-bucket-${AWS::AccountId}-${AWS::Region}" PublicAccessBlockConfiguration : BlockPublicAcls : true BlockPublicPolicy : true IgnorePublicAcls : true RestrictPublicBuckets : true BucketEncryption : ServerSideEncryptionConfiguration : - ServerSideEncryptionByDefault : SSEAlgorithm : aws : kms KMSMasterKeyID : !Ref S3KmsKey BucketKeyEnabled : true VersioningConfiguration : Status : Enabled LifecycleConfiguration : Rules : - Id : ArchiveOldVersions Status : Enabled NoncurrentVersionExpiration : NoncurrentDays : 90 Tags : - Key : Environment Value : !Ref Environment - Key : Encrypted Value : "true" AWS Secrets Manager Secrets Manager with Automatic Rotation Resources :

Database credentials secret

DatabaseSecret : Type : AWS : : SecretsManager : : Secret Properties : Name : !Sub "${AWS::StackName}/database/credentials" Description : "Database credentials with automatic rotation" SecretString : !Sub | { "username": "${DBUsername}", "password": "${DBPassword}", "host": "${DBHost}", "port": "${DBPort}", "dbname": "${DBName}", "engine": "postgresql" } KmsKeyId : !Ref SecretsKmsKeyId

Enable automatic rotation

RotationRules : AutomaticallyAfterDays : 30

Rotation Lambda configuration

RotationLambdaARN : !GetAtt SecretRotationFunction.Arn Tags : - Key : Environment Value : !Ref Environment - Key : ManagedBy Value : CloudFormation - Key : RotationEnabled Value : "true"

Secret with resource-based policy

ApiSecret : Type : AWS : : SecretsManager : : Secret Properties : Name : !Sub "${AWS::StackName}/api/keys" Description : "API keys for external service authentication" SecretString : !Sub | { "api_key": "${ExternalApiKey}", "api_secret": "${ExternalApiSecret}", "endpoint": "https://api.example.com" } KmsKeyId : !Ref SecretsKmsKeyId

Resource-based policy for access control

ResourcePolicy : Version : "2012-10-17" Statement : - Sid : "AllowLambdaAccess" Effect : Allow Principal : AWS : !Sub "arn:aws:iam::${AWS::AccountId}:role/LambdaExecutionRole" Action : - secretsmanager : GetSecretValue - secretsmanager : DescribeSecret Resource : "" Condition : StringEquals : aws:ResourceTag/Environment : !Ref Environment - Sid : "DenyUnencryptedAccess" Effect : Deny Principal : "" Action : - secretsmanager : GetSecretValue Resource : "*" Condition : StringEquals : kms:ViaService : !Sub "secretsmanager.${AWS::Region}.amazonaws.com" StringNotEquals : kms:EncryptContext : !Sub "secretsmanager:${AWS::StackName}"

Secret with cross-account access

SharedSecret : Type : AWS : : SecretsManager : : Secret Properties : Name : !Sub "${AWS::StackName}/shared/credentials" Description : "Secret shared across accounts" SecretString : !Sub | { "shared_key": "${SharedKey}", "shared_value": "${SharedValue}" } KmsKeyId : !Ref SecretsKmsKeyId

Cross-account access policy

ResourcePolicy : Version : "2012-10-17" Statement : - Sid : "AllowCrossAccountRead" Effect : Allow Principal : AWS : - !Sub "arn:aws:iam::${ProductionAccountId}:role/SharedSecretReader" Action : - secretsmanager : GetSecretValue - secretsmanager : DescribeSecret Resource : "*" SSM Parameter Store with SecureString Parameters :

SSM Parameter for database connection

DBCredentialsParam : Type : AWS : : SSM : : Parameter : : Value<SecureString

NoEcho : true Description : Database credentials from SSM Parameter Store Value : !Sub "/${Environment}/database/credentials"

SSM Parameter with specific path

ApiKeyParam : Type : AWS : : SSM : : Parameter : : Value<SecureString

NoEcho : true Description : API key for external service Value : !Sub "/${Environment}/external-api/key" Resources :

Lambda function using SSM parameters

SecureLambdaFunction : Type : AWS : : Lambda : : Function Properties : FunctionName : !Sub "${AWS::StackName}-secure-function" Runtime : python3.11 Handler : handler.handler Code : S3Bucket : !Ref CodeBucket S3Key : lambda/secure - function.zip Role : !GetAtt LambdaExecutionRole.Arn Environment : Variables : DB_CREDENTIALS_SSM_PATH : !Sub "/${Environment}/database/credentials" API_KEY_SSM_PATH : !Sub "/${Environment}/external-api/key" IAM Security - Least Privilege IAM Role with Granular Policies Resources :

Lambda Execution Role with minimal permissions

LambdaExecutionRole : Type : AWS : : IAM : : Role Properties : RoleName : !Sub "${AWS::StackName}-lambda-role" AssumeRolePolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : Service : lambda.amazonaws.com Action : sts : AssumeRole Condition : StringEquals : aws:SourceAccount : !Ref AWS : : AccountId lambda:SourceFunctionArn : !Ref SecureLambdaFunctionArn

Permissions boundary for enhanced security

PermissionsBoundary : !Ref PermissionsBoundaryPolicy ManagedPolicyArns : - arn : aws : iam : : aws : policy/service - role/AWSLambdaBasicExecutionRole Policies :

Policy for specific secrets access

- PolicyName : SecretsAccessPolicy PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - secretsmanager : GetSecretValue - secretsmanager : DescribeSecret Resource : !Ref DatabaseSecretArn Condition : StringEquals : secretsmanager:SecretTarget : !Sub "${DatabaseSecretArn}:${DatabaseSecret}" - Effect : Allow Action : - secretsmanager : GetSecretValue Resource : !Ref ApiSecretArn

Policy for specific S3 access

- PolicyName : S3AccessPolicy PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - s3 : GetObject - s3 : PutObject Resource : - !Sub "${DataBucket.Arn}/" - !Sub "${DataBucket.Arn}" Condition : StringEquals : s3:ResourceAccount : !Ref AWS : : AccountId - Effect : Deny Action : - s3 : DeleteObject Resource : - !Sub "${DataBucket.Arn}/*" Condition : Bool : aws:MultiFactorAuthPresent : true

Policy for CloudWatch Logs

- PolicyName : CloudWatchLogsPolicy PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - logs : CreateLogGroup - logs : CreateLogStream - logs : PutLogEvents Resource : !Sub "${LogGroup.Arn}:*" Tags : - Key : Environment Value : !Ref Environment - Key : LeastPrivilege Value : "true"

Permissions Boundary Policy

PermissionsBoundaryPolicy : Type : AWS : : IAM : : ManagedPolicy Properties : Description : "Permissions boundary for Lambda execution role" PolicyDocument : Version : "2012-10-17" Statement : - Sid : "DenyAccessToAllExceptSpecified" Effect : Deny Action : - "" Resource : "" Condition : StringNotEqualsIfExists : aws:RequestedRegion : - !Ref AWS : : Region ArnNotEqualsIfExists : aws:SourceArn : !Ref AllowedResourceArns IAM Policy for Cross-Account Access Resources :

Role for cross-account access

CrossAccountRole : Type : AWS : : IAM : : Role Properties : RoleName : !Sub "${AWS::StackName}-cross-account-role" AssumeRolePolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : AWS : - !Sub "arn:aws:iam::${ProductionAccountId}:root" - !Sub "arn:aws:iam::${StagingAccountId}:role/CrossAccountAccessRole" Action : sts : AssumeRole Condition : StringEquals : aws:PrincipalAccount : !Ref ProductionAccountId Bool : aws:MultiFactorAuthPresent : true Policies : - PolicyName : CrossAccountReadOnlyPolicy PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - s3 : GetObject - s3 : List Resource : - !Sub "${SharedBucket.Arn}" - !Sub "${SharedBucket.Arn}/" - Effect : Allow Action : - dynamodb : Query - dynamodb : Scan - dynamodb : GetItem Resource : - !Sub "${SharedTable.Arn}" - !Sub "${SharedTable.Arn}/index/" - Effect : Deny Action : - s3 : DeleteObject - s3 : PutObject Resource : - !Sub "${SharedBucket.Arn}/*" VPC Security Security Groups with Restrictive Rules Resources :

Security Group for application

ApplicationSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupName : !Sub "${AWS::StackName}-app-sg" GroupDescription : "Security group for application tier" VpcId : !Ref VPCId Tags : - Key : Name Value : !Sub "${AWS::StackName}-app-sg" - Key : Environment Value : !Ref Environment

Inbound rules - only necessary traffic

SecurityGroupIngress :

HTTP from ALB

- IpProtocol : tcp FromPort : 80 ToPort : 80 SourceSecurityGroupId : !Ref ALBSecurityGroup Description : "HTTP from ALB"

HTTPS from ALB

- IpProtocol : tcp FromPort : 443 ToPort : 443 SourceSecurityGroupId : !Ref ALBSecurityGroup Description : "HTTPS from ALB"

SSH from bastion only (if needed)

- IpProtocol : tcp FromPort : 22 ToPort : 22 SourceSecurityGroupId : !Ref BastionSecurityGroup Description : "SSH access from bastion"

Custom TCP for internal services

- IpProtocol : tcp FromPort : 8080 ToPort : 8080 SourceSecurityGroupId : !Ref InternalSecurityGroup Description : "Internal service communication"

Outbound rules - limited

SecurityGroupEgress :

HTTPS outbound for API calls

- IpProtocol : tcp FromPort : 443 ToPort : 443 CidrIp : 0.0.0.0/0 Description : "HTTPS outbound"

DNS outbound

- IpProtocol : udp FromPort : 53 ToPort : 53 CidrIp : 10.0.0.0/16 Description : "DNS outbound for VPC"

Security Group for database

DatabaseSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupName : !Sub "${AWS::StackName}-db-sg" GroupDescription : "Security group for database tier" VpcId : !Ref VPCId Tags : - Key : Name Value : !Sub "${AWS::StackName}-db-sg"

Inbound - only from application security group

SecurityGroupIngress : - IpProtocol : tcp FromPort : 5432 ToPort : 5432 SourceSecurityGroupId : !Ref ApplicationSecurityGroup Description : "PostgreSQL from application tier"

Outbound - minimum required

SecurityGroupEgress : - IpProtocol : tcp FromPort : 443 ToPort : 443 CidrIp : 0.0.0.0/0 Description : "HTTPS for updates and patches"

Security Group for ALB

ALBSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupName : !Sub "${AWS::StackName}-alb-sg" GroupDescription : "Security group for ALB" VpcId : !Ref VPCId SecurityGroupIngress :

HTTP from internet

- IpProtocol : tcp FromPort : 80 ToPort : 80 CidrIp : 0.0.0.0/0 Description : "HTTP from internet"

HTTPS from internet

- IpProtocol : tcp FromPort : 443 ToPort : 443 CidrIp : 0.0.0.0/0 Description : "HTTPS from internet" SecurityGroupEgress : - IpProtocol : tcp FromPort : 80 ToPort : 80 SourceSecurityGroupId : !Ref ApplicationSecurityGroup Description : "Forward to application"

VPC Endpoint for Secrets Manager

SecretsManagerVPCEndpoint : Type : AWS : : EC2 : : VPCEndpoint Properties : VpcId : !Ref VPCId ServiceName : !Sub "com.amazonaws.${AWS::Region}.secretsmanager" VpcEndpointType : Interface Subnets : - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 SecurityGroups : - !Ref ApplicationSecurityGroup PrivateDnsEnabled : true TLS/SSL Certificates with ACM Certificate Manager for API Gateway Resources :

SSL Certificate for domain

SSLCertificate : Type : AWS : : CertificateManager : : Certificate Properties : DomainName : !Ref DomainName SubjectAlternativeNames : - !Sub "*.${DomainName}" - !Ref AdditionalDomainName ValidationMethod : DNS DomainValidationOptions : - DomainName : !Ref DomainName Route53HostedZoneId : !Ref HostedZoneId Options : CertificateTransparencyLoggingPreference : ENABLED Tags : - Key : Environment Value : !Ref Environment - Key : ManagedBy Value : CloudFormation

Certificate for regional API Gateway

RegionalCertificate : Type : AWS : : CertificateManager : : Certificate Properties : DomainName : !Sub "${Environment}.${DomainName}" ValidationMethod : DNS DomainValidationOptions : - DomainName : !Sub "${Environment}.${DomainName}" Route53HostedZoneId : !Ref HostedZoneId

API Gateway with TLS 1.2+

SecureApiGateway : Type : AWS : : ApiGateway : : RestApi Properties : Name : !Sub "${AWS::StackName}-secure-api" Description : "Secure REST API with TLS enforcement" EndpointConfiguration : Types : - REGIONAL MinimumCompressionSize : 1024

Policy to enforce HTTPS

Policy : Version : "2012-10-17" Statement : - Effect : Deny Principal : "" Action : execute - api : Invoke Resource : !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SecureApiGateway}/" Condition : Bool : aws:SecureTransport : "false"

Custom Domain per API Gateway

ApiGatewayDomain : Type : AWS : : ApiGateway : : DomainName Properties : DomainName : !Sub "api.${DomainName}" RegionalCertificateArn : !Ref RegionalCertificate EndpointConfiguration : Types : - REGIONAL

Route 53 record per dominio API

ApiGatewayDNSRecord : Type : AWS : : Route53 : : RecordSet Properties : Name : !Sub "api.${DomainName}." Type : A AliasTarget : DNSName : !GetAtt ApiGatewayRegionalHostname.RegionalHostname HostedZoneId : !GetAtt ApiGatewayRegionalHostname.RegionalHostedZoneId EvaluateTargetHealth : false HostedZoneId : !Ref HostedZoneId

Lambda Function URL con AuthType AWS_IAM

SecureLambdaUrl : Type : AWS : : Lambda : : Url Properties : AuthType : AWS_IAM TargetFunctionArn : !GetAtt SecureLambdaFunction.Arn Cors : AllowCredentials : true AllowHeaders : - Authorization - Content - Type AllowMethods : - GET - POST AllowOrigins : - !Ref AllowedOrigin MaxAge : 86400 InvokeMode : BUFFERED Parameter Security Best Practices AWS-Specific Parameter Types with Validation Parameters :

AWS-specific types for automatic validation

VPCId : Type : AWS : : EC2 : : VPC : : Id Description : VPC ID for deployment SubnetIds : Type : List<AWS : : EC2 : : Subnet : : Id

Description : Subnet IDs for private subnets SecurityGroupIds : Type : List<AWS : : EC2 : : SecurityGroup : : Id

Description : Security group IDs DatabaseInstanceIdentifier : Type : AWS : : RDS : : DBInstance : : Identifier Description : RDS instance identifier KMSKeyArn : Type : AWS : : KMS : : Key : : Arn Description : KMS key ARN for encryption SecretArn : Type : AWS : : SecretsManager : : Secret : : Arn Description : Secrets Manager secret ARN LambdaFunctionArn : Type : AWS : : Lambda : : Function : : Arn Description : Lambda function ARN

SSM Parameter with secure string

DatabasePassword : Type : AWS : : SSM : : Parameter : : Value<SecureString

NoEcho : true Description : Database password from SSM

Custom parameters with constraints

DBUsername : Type : String Description : Database username Default : appuser MinLength : 1 MaxLength : 63 AllowedPattern : "[a-zA-Z][a-zA-Z0-9_]*" ConstraintDescription : Must start with letter , alphanumeric and underscores only DBPort : Type : Number Description : Database port Default : 5432 MinValue : 1024 MaxValue : 65535 MaxConnections : Type : Number Description : Maximum database connections Default : 100 MinValue : 10 MaxValue : 65535 EnvironmentName : Type : String Description : Deployment environment Default : dev AllowedValues : - dev - staging - production ConstraintDescription : Must be dev , staging , or production Outputs and Secure Cross-Stack References Export with Naming Convention Outputs :

Export for cross-stack references

VPCIdExport : Description : VPC ID for network stack Value : !Ref VPC Export : Name : !Sub "${AWS::StackName}-VPCId" ApplicationSecurityGroupIdExport : Description : Application security group ID Value : !Ref ApplicationSecurityGroup Export : Name : !Sub "${AWS::StackName}-AppSecurityGroupId" DatabaseSecurityGroupIdExport : Description : Database security group ID Value : !Ref DatabaseSecurityGroup Export : Name : !Sub "${AWS::StackName}-DBSecurityGroupId" KMSKeyArnExport : Description : KMS key ARN for encryption Value : !GetAtt ApplicationKmsKey.Arn Export : Name : !Sub "${AWS::StackName}-KMSKeyArn" DatabaseSecretArnExport : Description : Database secret ARN Value : !Ref DatabaseSecret Export : Name : !Sub "${AWS::StackName}-DatabaseSecretArn" SSLCertificateArnExport : Description : SSL certificate ARN Value : !Ref SSLCertificate Export : Name : !Sub "${AWS::StackName}-SSLCertificateArn" Import from Network Stack Parameters : NetworkStackName : Type : String Description : Name of the network stack Resources :

Import values from network stack

VPCId : Type : AWS : : EC2 : : VPC Properties : CidrBlock : !Select [ 0 , !Split [ "," , !ImportValue !Sub "$ { NetworkStackName } - VPCcidrs" ] ] ApplicationSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupName : !Sub "${AWS::StackName}-app-sg" VpcId : !ImportValue !Sub "$ { NetworkStackName } - VPCId" SecurityGroupIngress : - IpProtocol : tcp FromPort : 80 ToPort : 80 SourceSecurityGroupId : !ImportValue !Sub "$ { NetworkStackName } - ALBSecurityGroupId" CloudWatch Logs Encryption Log Group with KMS Encryption Resources :

Encrypted CloudWatch Log Group

EncryptedLogGroup : Type : AWS : : Logs : : LogGroup Properties : LogGroupName : !Sub "/aws/lambda/${AWS::StackName}-function" RetentionInDays : 30 KmsKeyId : !Ref ApplicationKmsKey

Data protection policy

LogGroupClass : STANDARD Tags : - Key : Environment Value : !Ref Environment - Key : Encrypted Value : "true"

Metric Filter for security events

SecurityEventMetricFilter : Type : AWS : : Logs : : MetricFilter Properties : LogGroupName : !Ref EncryptedLogGroup FilterPattern : '[ERROR, WARNING, "Access Denied", "Unauthorized"]' MetricTransformations : - MetricValue : "1" MetricNamespace : !Sub "${AWS::StackName}/Security" MetricName : SecurityEvents

Alarm for security errors

SecurityAlarm : Type : AWS : : CloudWatch : : Alarm Properties : AlarmName : !Sub "${AWS::StackName}-security-errors" AlarmDescription : Alert on security - related errors MetricName : SecurityEvents Namespace : !Sub "${AWS::StackName}/Security" Statistic : Sum Period : 60 EvaluationPeriods : 5 Threshold : 1 ComparisonOperator : GreaterThanThreshold AlarmActions : - !Ref SecurityAlertTopic

SNS Topic for security alerts

SecurityAlertTopic : Type : AWS : : SNS : : Topic Properties : TopicName : !Sub "${AWS::StackName}-security-alerts" Defense in Depth Stack with Multiple Security Layers AWSTemplateFormatVersion : 2010-09-09 Description : Defense in depth security architecture Resources :

Layer 1: Network Security - Security Groups

WebTierSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupDescription : "Web tier security group" VpcId : !Ref VPCId SecurityGroupIngress : - IpProtocol : tcp FromPort : 443 ToPort : 443 CidrIp : 0.0.0.0/0 Description : "HTTPS from internet" AppTierSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupDescription : "App tier security group" VpcId : !Ref VPCId SecurityGroupIngress : - IpProtocol : tcp FromPort : 8080 ToPort : 8080 SourceSecurityGroupId : !Ref WebTierSecurityGroup

Layer 2: Encryption - KMS

DataEncryptionKey : Type : AWS : : KMS : : Key Properties : Description : "Data encryption key" KeyPolicy : Version : "2012-10-17" Statement : - Sid : "EnableIAMPoliciesForKeyManagement" Effect : Allow Principal : AWS : !Sub "arn:aws:iam::${AWS::AccountId}:role/AdminRole" Action : kms : * Resource : "" - Sid : "AllowEncryptionOperations" Effect : Allow Principal : AWS : !Sub "arn:aws:iam::${AWS::AccountId}:role/AppRole" Action : - kms : Encrypt - kms : Decrypt Resource : ""

Layer 3: Secrets Management

ApplicationSecret : Type : AWS : : SecretsManager : : Secret Properties : Name : !Sub "${AWS::StackName}/application/credentials" SecretString : "{}" KmsKeyId : !Ref DataEncryptionKey

Layer 4: IAM Least Privilege

ApplicationRole : Type : AWS : : IAM : : Role Properties : RoleName : !Sub "${AWS::StackName}-app-role" AssumeRolePolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : Service : ecs.amazonaws.com Action : sts : AssumeRole Policies : - PolicyName : MinimalSecretsAccess PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - secretsmanager : GetSecretValue Resource : !Ref ApplicationSecret

Layer 5: Logging and Monitoring

AuditLogGroup : Type : AWS : : Logs : : LogGroup Properties : LogGroupName : !Sub "/aws/${AWS::StackName}/audit" RetentionInDays : 365 KmsKeyId : !Ref DataEncryptionKey

Layer 6: WAF for API protection

WebACL : Type : AWS : : WAFv2 : : WebACL Properties : Name : !Sub "${AWS::StackName}-waf" Scope : REGIONAL DefaultAction : Allow : CustomRequestHandling : InsertHeaders : - Name : X - Frame - Options Value : DENY Rules : - Name : BlockSQLInjection Priority : 1 Statement : SqliMatchStatement : FieldToMatch : Body : OversizeHandling : CONTINUE SensitivityLevel : HIGH Action : Block : CustomResponse : ResponseCode : 403 ResponseBody : "Request blocked due to SQL injection" VisibilityConfig : SampledRequestsEnabled : true CloudWatchMetricsEnabled : true MetricName : BlockSQLInjection - Name : BlockXSS Priority : 2 Statement : XssMatchStatement : FieldToMatch : QueryString : OversizeHandling : CONTINUE Action : Block : VisibilityConfig : SampledRequestsEnabled : true CloudWatchMetricsEnabled : true MetricName : BlockXSS - Name : RateLimit Priority : 3 Statement : RateBasedStatement : Limit : 2000 EvaluationWindowSec : 60 Action : Block : CustomResponse : ResponseCode : 429 ResponseBody : "Too many requests" VisibilityConfig : SampledRequestsEnabled : true CloudWatchMetricsEnabled : true MetricName : RateLimit VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : !Sub "${AWS::StackName}-WebACL" SampledRequestsEnabled : true Best Practices Encryption Always use KMS with customer-managed keys for sensitive data Enable automatic key rotation (max 365 days) Use S3 bucket keys to reduce KMS costs Encrypt CloudWatch Logs with KMS Implement envelope encryption for large data Secrets Management Use Secrets Manager for automatic rotation Reference secrets via ARN, not hard-coded Use resource-based policies for granular access Implement encryption context for auditing Limit access with IAM conditions IAM Security Apply least privilege in all policies Use permissions boundaries to limit escalation Enable MFA for administrative roles Implement condition keys for region/endpoint Regular audit with IAM Access Analyzer Network Security Security groups with minimal rules Deny default outbound where possible Use VPC endpoints for AWS services Implement private subnets for backend tiers Use Network ACLs as additional layer TLS/SSL Use ACM for managed certificates Enforce HTTPS with resource policies Configure minimum TLS 1.2 Use HSTS headers Renew certificates before expiration Monitoring Enable CloudTrail for audit trail Create metrics for security events Configure alarms for suspicious activity Appropriate log retention (min 90 days) Use GuardDuty for threat detection Related Resources AWS KMS Documentation AWS Secrets Manager IAM Best Practices Security Groups AWS WAF Additional Files For complete details on resources and their properties, see: REFERENCE.md - Detailed reference guide for all CloudFormation security resources EXAMPLES.md - Complete production-ready examples for security scenarios CloudFormation Stack Management Best Practices Stack Policies Stack Policies prevent accidental updates to critical infrastructure resources. Use them to protect production resources from unintended modifications. Resources : ProductionStackPolicy : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : !Sub "https://${BucketName}.s3.amazonaws.com/production-stack.yaml" StackPolicyBody : Version : "2012-10-17" Statement : - Effect : Allow Action : Update : * Principal : "" Resource : "" - Effect : Deny Action : - Update : Replace - Update : Delete Principal : "*" Resource : - LogicalResourceId/ProductionDatabase - LogicalResourceId/ProductionKmsKey Condition : StringEquals : aws:RequestedRegion : - us - east - 1 - us - west - 2

Inline stack policy for sensitive resources

SensitiveResourcesPolicy : Type : AWS : : CloudFormation : : StackPolicy Properties : PolicyDocument : Version : "2012-10-17" Statement : - Effect : Deny Action : Update : * Principal : "" Resource : "" Condition : StringEquals : aws:ResourceTag/Environment : production Not : StringEquals : aws:username : security - admin Termination Protection Enable termination protection to prevent accidental deletion of production stacks. This adds a safety layer for critical infrastructure. Resources :

Production stack with termination protection

ProductionDatabaseStack : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : !Sub "https://${BucketName}.s3.amazonaws.com/database.yaml" TerminationProtection : true Parameters : Environment : production InstanceClass : db.r6g.xlarge MultiAZ : true

Stack with conditional termination protection

ApplicationStack : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : !Sub "https://${BucketName}.s3.amazonaws.com/application.yaml" TerminationProtection : !If [ IsProduction , true , false ] Parameters : Environment : !Ref Environment Drift Detection Detect configuration drift in your CloudFormation stacks to identify unauthorized or unexpected changes. Resources :

Custom resource for drift detection

DriftDetectionFunction : Type : AWS : : Lambda : : Function Properties : FunctionName : !Sub "${AWS::StackName}-drift-detector" Runtime : python3.11 Handler : drift_detector.handler Role : !GetAtt DriftDetectionRole.Arn Code : S3Bucket : !Ref CodeBucket S3Key : lambda/drift - detector.zip Environment : Variables : STACK_NAME : !Ref StackName SNS_TOPIC_ARN : !Ref DriftAlertTopic Timeout : 300

Scheduled drift detection

DriftDetectionSchedule : Type : AWS : : Events : : Rule Properties : Name : !Sub "${AWS::StackName}-drift-schedule" ScheduleExpression : rate(1 day) State : ENABLED Targets : - Arn : !GetAtt DriftDetectionFunction.Arn Id : DriftDetectionFunction

Permission for EventBridge to invoke Lambda

DriftDetectionPermission : Type : AWS : : Lambda : : Permission Properties : FunctionName : !Ref DriftDetectionFunction Action : lambda : InvokeFunction Principal : events.amazonaws.com SourceArn : !GetAtt DriftDetectionSchedule.Arn

SNS topic for drift alerts

DriftAlertTopic : Type : AWS : : SNS : : Topic Properties : TopicName : !Sub "${AWS::StackName}-drift-alerts" Drift Detection Python Handler import boto3 import json def handler ( event , context ) : cloudformation = boto3 . client ( 'cloudformation' ) sns = boto3 . client ( 'sns' ) stack_name = event . get ( 'STACK_NAME' , 'my-production-stack' ) topic_arn = event . get ( 'SNS_TOPIC_ARN' )

Detect drift

response

cloudformation . detect_stack_drift ( StackName = stack_name )

Wait for drift detection to complete

import time time . sleep ( 60 )

Get drift status

drift_status

cloudformation . describe_stack - drift - detection - status ( StackName = stack_name , DetectionId = response [ 'StackDriftDetectionId' ] )

Get resources with drift

resources

[ ] paginator = cloudformation . get_paginator ( 'list_stack_resources' ) for page in paginator . paginate ( StackName = stack_name ) : for resource in page [ 'StackResourceSummaries' ] : if resource [ 'DriftStatus' ] != 'IN_SYNC' : resources . append ( { 'LogicalId' : resource [ 'LogicalResourceId' ] , 'PhysicalId' : resource [ 'PhysicalResourceId' ] , 'DriftStatus' : resource [ 'DriftStatus' ] , 'Expected' : resource . get ( 'ExpectedResourceType' ) , 'Actual' : resource . get ( 'ActualResourceType' ) } )

Send alert if drift detected

if resources : message = f"Drift detected on stack { stack_name } :\n" for r in resources : message += f"- { r [ 'LogicalId' ] } : { r [ 'DriftStatus' ] } \n" sns . publish ( TopicArn = topic_arn , Subject = f"CloudFormation Drift Alert: { stack_name } " , Message = message ) return { 'statusCode' : 200 , 'body' : json . dumps ( { 'drift_status' : drift_status [ 'StackDriftStatus' ] , 'resources_with_drift' : len ( resources ) } ) } Change Sets Usage Use Change Sets to preview and review changes before applying them to production stacks. Resources :

Change set for stack update

ChangeSet : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : !Sub "https://${BucketName}.s3.amazonaws.com/updated-template.yaml" ChangeSetName : !Sub "${AWS::StackName}-update-changeset" ChangeSetType : UPDATE Parameters : Environment : !Ref Environment InstanceType : !Ref NewInstanceType Capabilities : - CAPABILITY_IAM - CAPABILITY_NAMED_IAM

Nested change set for review

ReviewChangeSet : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : !Sub "https://${BucketName}.s3.amazonaws.com/review-template.yaml" ChangeSetName : !Sub "${AWS::StackName}-review-changeset" ChangeSetType : UPDATE Parameters : Environment : !Ref Environment Tags : - Key : ChangeSetType Value : review - Key : CreatedBy Value : CloudFormation Change Set Generation Script

!/bin/bash

Create a change set for review

aws cloudformation create-change-set \ --stack-name my-production-stack \ --change-set-name production-update-changeset \ --template-url https://my-bucket.s3.amazonaws.com/updated-template.yaml \ --parameters ParameterKey = Environment,ParameterValue = production \ --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM

Wait for change set creation

aws cloudformation wait change-set-create-complete \ --stack-name my-production-stack \ --change-set-name production-update-changeset

Describe change set to see what will change

aws cloudformation describe-change-set \ --stack-name my-production-stack \ --change-set-name production-update-changeset

Execute change set if changes look good

aws cloudformation execute-change-set \ --stack-name my-production-stack \ --change-set-name production-update-changeset Stack Update with Rollback Triggers Resources :

Production stack with rollback configuration

ProductionStack : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : !Sub "https://${BucketName}.s3.amazonaws.com/production.yaml" TimeoutInMinutes : 60 RollbackConfiguration : RollbackTriggers : - Arn : !Sub "arn:aws:cloudwatch:${AWS::Region}:${AWS::AccountId}:alarm:ProductionCPUHigh" Type : AWS : : CloudWatch : : Alarm - Arn : !Sub "arn:aws:cloudwatch:${AWS::Region}:${AWS::AccountId}:alarm:ProductionLatencyHigh" Type : AWS : : CloudWatch : : Alarm MonitoringTimeInMinutes : 15 NotificationARNs : - !Ref UpdateNotificationTopic

CloudWatch alarms for rollback

ProductionCPUHigh : Type : AWS : : CloudWatch : : Alarm Properties : AlarmName : !Sub "${AWS::StackName}-CPU-High" AlarmDescription : Trigger rollback if CPU exceeds 80% MetricName : CPUUtilization Namespace : AWS/EC2 Statistic : Average Period : 60 EvaluationPeriods : 5 Threshold : 80 ComparisonOperator : GreaterThanThreshold AlarmActions : - !Ref UpdateNotificationTopic

SNS topic for notifications

UpdateNotificationTopic
:
Type
:
AWS
:
:
SNS
:
:
Topic
Properties
:
TopicName
:
!Sub
"${AWS::StackName}-update-notifications"
Best Practices for Stack Management
Enable Termination Protection
Always enable for production stacks
Use as a safety mechanism against accidental deletion
Requires manual disabling before deletion
Use Stack Policies
Protect critical resources from unintended updates
Use Deny statements for production databases, KMS keys, and IAM roles
Apply conditions based on region, user, or tags
Implement Drift Detection
Run drift detection regularly (daily for production)
Alert on any drift detection
Investigate and remediate drift immediately
Use Change Sets
Always use Change Sets for production updates
Review changes before execution
Use descriptive change set names
Configure Rollback Triggers
Set up CloudWatch alarms for critical metrics
Configure monitoring time to allow stabilization
Test rollback triggers in non-production first
Implement Change Management
Require approval for production changes
Use CodePipeline with manual approval gates
Document all changes in change log
Use Stack Sets for Multi-Account
Deploy infrastructure consistently across accounts
Use StackSets for organization-wide policies
Implement drift detection at organization level
Constraints and Warnings
Resource Limits
Security Group Rules
Maximum 60 inbound and 60 outbound rules per security group
Security Groups
Maximum 500 security groups per VPC
NACL Rules
Maximum 20 inbound and 20 outbound rules per NACL per subnet
VPC Limits
Maximum 5 VPCs per region (soft limit, can be increased)
Security Constraints
Default Security Groups
Default security groups cannot be deleted
Security Group References
Security group references cannot span VPC peering in some cases
NACL Stateless
NACLs are stateless; return traffic must be explicitly allowed
Flow Logs
VPC Flow Logs generate significant CloudWatch Logs costs
Operational Constraints
CIDR Overlap
VPC CIDR blocks cannot overlap with peered VPCs or on-prem networks
ENI Limits
Each instance type has maximum ENI limits; affects scaling
Elastic IP Limits
Each account has limited number of Elastic IPs
NAT Gateway Limits
Each AZ can have only one NAT gateway per subnet
Network Constraints
Transit Gateway
Transit Gateway attachments have per-AZ and per-account limits
VPN Connections
VPN connections have bandwidth limitations
Direct Connect
Direct Connect requires physical infrastructure and lead time
PrivateLink
VPC Endpoint services have availability constraints
Cost Considerations
NAT Gateway
NAT gateways incur hourly costs plus data processing costs
Traffic Mirroring
Traffic mirroring doubles data transfer costs
Flow Logs
Flow logs storage and analysis add significant costs
PrivateLink
Interface VPC endpoints incur hourly and data processing costs
Access Control Constraints
IAM vs Resource Policies
Some services require both IAM and resource-based policies
SCP Limits
Service Control Policies have character limits and complexity constraints
Permission Boundaries
Permission boundaries do not limit service actions
Session Policies
Session policies cannot grant more permissions than IAM policies Additional Files
返回排行榜