aws-cloud-architecture
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAWS Cloud Architecture
AWS云架构
A comprehensive skill for designing, implementing, and operating production-grade AWS cloud architectures following the AWS Well-Architected Framework.
这是一份遵循AWS架构完善框架,用于设计、实施和运维生产级AWS云架构的全面指南。
Table of Contents
目录
AWS Well-Architected Framework
AWS架构完善框架
The AWS Well-Architected Framework provides best practices across six pillars:
AWS架构完善框架涵盖六大支柱的最佳实践:
1. Operational Excellence
1. 运营卓越
- Automate infrastructure provisioning and configuration
- Monitor and measure system performance
- Continuously improve processes and procedures
- 自动化基础设施配置与部署
- 监控并衡量系统性能
- 持续优化流程与程序
2. Security
2. 安全
- Implement strong identity foundation
- Enable traceability and audit logging
- Apply security at all layers
- Protect data in transit and at rest
- 构建强身份基础
- 启用可追溯性与审计日志
- 在所有层级应用安全措施
- 保护传输中与静态数据
3. Reliability
3. 可靠性
- Automatically recover from failure
- Test recovery procedures
- Scale horizontally for resilience
- Manage change through automation
- 实现故障自动恢复
- 测试恢复流程
- 通过横向扩展提升韧性
- 自动化变更管理
4. Performance Efficiency
4. 性能效率
- Use appropriate resource types and sizes
- Monitor performance and adapt
- Leverage serverless architectures
- Experiment with new technologies
- 使用合适的资源类型与规格
- 监控性能并动态调整
- 利用无服务器架构
- 尝试新技术
5. Cost Optimization
5. 成本优化
- Adopt consumption-based pricing
- Measure and monitor spending
- Use cost-effective resources
- Optimize over time
- 采用基于消耗的定价模式
- 计量并监控支出
- 使用高性价比资源
- 持续优化成本
6. Sustainability
6. 可持续性
- Understand environmental impact
- Maximize utilization of resources
- Use managed services
- Reduce downstream impact
- 了解环境影响
- 最大化资源利用率
- 使用托管服务
- 降低下游影响
Compute Services
计算服务
Amazon EC2 (Elastic Compute Cloud)
Amazon EC2 (弹性计算云)
EC2 provides resizable compute capacity in the cloud, offering complete control over computing resources.
EC2提供云中可调整的计算容量,让您完全控制计算资源。
EC2 Instance Types
EC2实例类型
bash
undefinedbash
undefinedList available instance types in a region
列出区域内可用的实例类型
aws ec2 describe-instance-types
--region us-east-1
--query 'InstanceTypes[*].[InstanceType,VCpuInfo.DefaultVCpus,MemoryInfo.SizeInMiB]'
--output table
--region us-east-1
--query 'InstanceTypes[*].[InstanceType,VCpuInfo.DefaultVCpus,MemoryInfo.SizeInMiB]'
--output table
undefinedaws ec2 describe-instance-types
--region us-east-1
--query 'InstanceTypes[*].[InstanceType,VCpuInfo.DefaultVCpus,MemoryInfo.SizeInMiB]'
--output table
--region us-east-1
--query 'InstanceTypes[*].[InstanceType,VCpuInfo.DefaultVCpus,MemoryInfo.SizeInMiB]'
--output table
undefinedLaunch EC2 Instance with User Data
使用用户数据启动EC2实例
yaml
undefinedyaml
undefinedCloudFormation: EC2 Instance with Auto Scaling
CloudFormation: 带自动扩缩容的EC2实例
AWSTemplateFormatVersion: '2010-09-09'
Description: EC2 instance with user data for web server
Parameters:
InstanceType:
Type: String
Default: t3.micro
AllowedValues:
- t3.micro
- t3.small
- t3.medium
Description: EC2 instance type
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: EC2 key pair for SSH access
Resources:
WebServerInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
ImageId: !Sub '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
KeyName: !Ref KeyName
SecurityGroupIds:
- !Ref WebServerSecurityGroup
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello from AWS CloudFormation</h1>" > /var/www/html/index.html
Tags:
- Key: Name
Value: WebServer
- Key: Environment
Value: Production
WebServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for web server
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 10.0.0.0/8
Tags:
- Key: Name
Value: WebServerSG
Outputs:
InstanceId:
Description: EC2 instance ID
Value: !Ref WebServerInstance
PublicIP:
Description: Public IP address
Value: !GetAtt WebServerInstance.PublicIp
undefinedAWSTemplateFormatVersion: '2010-09-09'
Description: 用于Web服务器的带用户数据的EC2实例
Parameters:
InstanceType:
Type: String
Default: t3.micro
AllowedValues:
- t3.micro
- t3.small
- t3.medium
Description: EC2实例类型
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: 用于SSH访问的EC2密钥对
Resources:
WebServerInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
ImageId: !Sub '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
KeyName: !Ref KeyName
SecurityGroupIds:
- !Ref WebServerSecurityGroup
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello from AWS CloudFormation</h1>" > /var/www/html/index.html
Tags:
- Key: Name
Value: WebServer
- Key: Environment
Value: Production
WebServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Web服务器安全组
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 10.0.0.0/8
Tags:
- Key: Name
Value: WebServerSG
Outputs:
InstanceId:
Description: EC2实例ID
Value: !Ref WebServerInstance
PublicIP:
Description: 公网IP地址
Value: !GetAtt WebServerInstance.PublicIp
undefinedEC2 Auto Scaling Group
EC2自动扩缩容组
yaml
undefinedyaml
undefinedCloudFormation: Auto Scaling Group with Launch Template
CloudFormation: 带启动模板的自动扩缩容组
LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: WebServerLaunchTemplate
LaunchTemplateData:
ImageId: !Sub '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
InstanceType: t3.micro
SecurityGroupIds:
- !Ref WebServerSecurityGroup
IamInstanceProfile:
Arn: !GetAtt InstanceProfile.Arn
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install -y httpd aws-cli
systemctl start httpd
systemctl enable httpd
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
echo "<h1>Instance: $INSTANCE_ID</h1>" > /var/www/html/index.html
TagSpecifications:
- ResourceType: instance
Tags:
- Key: Name
Value: WebServer-ASG
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: WebServerASG
MinSize: 2
MaxSize: 10
DesiredCapacity: 2
HealthCheckType: ELB
HealthCheckGracePeriod: 300
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
VPCZoneIdentifier:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
TargetGroupARNs:
- !Ref TargetGroup
Tags:
- Key: Environment
Value: Production
PropagateAtLaunch: true
ScaleUpPolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName: !Ref AutoScalingGroup
Cooldown: 300
ScalingAdjustment: 1
ScaleDownPolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName: !Ref AutoScalingGroup
Cooldown: 300
ScalingAdjustment: -1
CPUAlarmHigh:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Scale up when CPU exceeds 70%
MetricName: CPUUtilization
Namespace: AWS/EC2
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 70
AlarmActions:
- !Ref ScaleUpPolicy
Dimensions:
- Name: AutoScalingGroupName
Value: !Ref AutoScalingGroup
ComparisonOperator: GreaterThanThreshold
CPUAlarmLow:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Scale down when CPU is below 30%
MetricName: CPUUtilization
Namespace: AWS/EC2
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 30
AlarmActions:
- !Ref ScaleDownPolicy
Dimensions:
- Name: AutoScalingGroupName
Value: !Ref AutoScalingGroup
ComparisonOperator: LessThanThreshold
undefinedLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: WebServerLaunchTemplate
LaunchTemplateData:
ImageId: !Sub '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
InstanceType: t3.micro
SecurityGroupIds:
- !Ref WebServerSecurityGroup
IamInstanceProfile:
Arn: !GetAtt InstanceProfile.Arn
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install -y httpd aws-cli
systemctl start httpd
systemctl enable httpd
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
echo "<h1>Instance: $INSTANCE_ID</h1>" > /var/www/html/index.html
TagSpecifications:
- ResourceType: instance
Tags:
- Key: Name
Value: WebServer-ASG
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: WebServerASG
MinSize: 2
MaxSize: 10
DesiredCapacity: 2
HealthCheckType: ELB
HealthCheckGracePeriod: 300
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
VPCZoneIdentifier:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
TargetGroupARNs:
- !Ref TargetGroup
Tags:
- Key: Environment
Value: Production
PropagateAtLaunch: true
ScaleUpPolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName: !Ref AutoScalingGroup
Cooldown: 300
ScalingAdjustment: 1
ScaleDownPolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName: !Ref AutoScalingGroup
Cooldown: 300
ScalingAdjustment: -1
CPUAlarmHigh:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: CPU使用率超过70%时扩容
MetricName: CPUUtilization
Namespace: AWS/EC2
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 70
AlarmActions:
- !Ref ScaleUpPolicy
Dimensions:
- Name: AutoScalingGroupName
Value: !Ref AutoScalingGroup
ComparisonOperator: GreaterThanThreshold
CPUAlarmLow:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: CPU使用率低于30%时缩容
MetricName: CPUUtilization
Namespace: AWS/EC2
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 30
AlarmActions:
- !Ref ScaleDownPolicy
Dimensions:
- Name: AutoScalingGroupName
Value: !Ref AutoScalingGroup
ComparisonOperator: LessThanThreshold
undefinedAWS Lambda
AWS Lambda
Serverless compute service that runs code in response to events.
事件驱动的无服务器计算服务。
Lambda Function with Python
Python编写的Lambda函数
yaml
undefinedyaml
undefinedCloudFormation: Lambda Function with API Gateway
CloudFormation: 带API网关的Lambda函数
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
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
- arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess
Policies:
- PolicyName: DynamoDBAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:Query
- dynamodb:Scan
Resource: !GetAtt DynamoDBTable.Arn
HelloWorldFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: HelloWorldFunction
Runtime: python3.11
Handler: index.lambda_handler
Role: !GetAtt LambdaExecutionRole.Arn
Timeout: 30
MemorySize: 256
Environment:
Variables:
TABLE_NAME: !Ref DynamoDBTable
STAGE: production
Code:
ZipFile: |
import json
import os
import boto3
from datetime import datetime
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(os.environ['TABLE_NAME'])
def lambda_handler(event, context):
try:
# Log the event
print(f"Event: {json.dumps(event)}")
# Extract data from event
body = json.loads(event.get('body', '{}'))
# Store in DynamoDB
response = table.put_item(
Item={
'id': context.request_id,
'timestamp': datetime.now().isoformat(),
'data': body,
'stage': os.environ['STAGE']
}
)
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps({
'message': 'Success',
'requestId': context.request_id
})
}
except Exception as e:
print(f"Error: {str(e)}")
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
TracingConfig:
Mode: ActiveundefinedLambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
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
- arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess
Policies:
- PolicyName: DynamoDBAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:Query
- dynamodb:Scan
Resource: !GetAtt DynamoDBTable.Arn
HelloWorldFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: HelloWorldFunction
Runtime: python3.11
Handler: index.lambda_handler
Role: !GetAtt LambdaExecutionRole.Arn
Timeout: 30
MemorySize: 256
Environment:
Variables:
TABLE_NAME: !Ref DynamoDBTable
STAGE: production
Code:
ZipFile: |
import json
import os
import boto3
from datetime import datetime
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(os.environ['TABLE_NAME'])
def lambda_handler(event, context):
try:
# Log the event
print(f"Event: {json.dumps(event)}")
# Extract data from event
body = json.loads(event.get('body', '{}'))
# Store in DynamoDB
response = table.put_item(
Item={
'id': context.request_id,
'timestamp': datetime.now().isoformat(),
'data': body,
'stage': os.environ['STAGE']
}
)
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps({
'message': 'Success',
'requestId': context.request_id
})
}
except Exception as e:
print(f"Error: {str(e)}")
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
TracingConfig:
Mode: ActiveundefinedLambda with S3 Event Trigger
带S3事件触发器的Lambda
python
undefinedpython
undefinedPython Lambda function for S3 event processing
处理S3事件的Python Lambda函数
import json
import urllib.parse
import boto3
from PIL import Image
import io
s3 = boto3.client('s3')
def lambda_handler(event, context):
"""
Process images uploaded to S3:
- Create thumbnails
- Extract metadata
- Store results in destination bucket
"""
# Get bucket and key from S3 event
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'])
try:
# Download image from S3
response = s3.get_object(Bucket=bucket, Key=key)
image_content = response['Body'].read()
# Open image with PIL
image = Image.open(io.BytesIO(image_content))
# Create thumbnail
thumbnail_size = (200, 200)
image.thumbnail(thumbnail_size)
# Save thumbnail to buffer
buffer = io.BytesIO()
image.save(buffer, format=image.format)
buffer.seek(0)
# Upload thumbnail to destination bucket
thumbnail_key = f"thumbnails/{key}"
s3.put_object(
Bucket=f"{bucket}-processed",
Key=thumbnail_key,
Body=buffer,
ContentType=response['ContentType']
)
print(f"Successfully created thumbnail: {thumbnail_key}")
return {
'statusCode': 200,
'body': json.dumps({
'original': key,
'thumbnail': thumbnail_key,
'size': image.size
})
}
except Exception as e:
print(f"Error processing image {key}: {str(e)}")
raise eundefinedimport json
import urllib.parse
import boto3
from PIL import Image
import io
s3 = boto3.client('s3')
def lambda_handler(event, context):
"""
处理上传到S3的图片:
- 创建缩略图
- 提取元数据
- 将结果存储到目标存储桶
"""
# 从S3事件中获取存储桶和键
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'])
try:
# 从S3下载图片
response = s3.get_object(Bucket=bucket, Key=key)
image_content = response['Body'].read()
# 用PIL打开图片
image = Image.open(io.BytesIO(image_content))
# 创建缩略图
thumbnail_size = (200, 200)
image.thumbnail(thumbnail_size)
# 将缩略图保存到缓冲区
buffer = io.BytesIO()
image.save(buffer, format=image.format)
buffer.seek(0)
# 将缩略图上传到目标存储桶
thumbnail_key = f"thumbnails/{key}"
s3.put_object(
Bucket=f"{bucket}-processed",
Key=thumbnail_key,
Body=buffer,
ContentType=response['ContentType']
)
print(f"Successfully created thumbnail: {thumbnail_key}")
return {
'statusCode': 200,
'body': json.dumps({
'original': key,
'thumbnail': thumbnail_key,
'size': image.size
})
}
except Exception as e:
print(f"Error processing image {key}: {str(e)}")
raise eundefinedAmazon ECS (Elastic Container Service)
Amazon ECS (弹性容器服务)
Container orchestration service supporting Docker containers.
支持Docker容器的容器编排服务。
ECS Cluster with Fargate
基于Fargate的ECS集群
yaml
undefinedyaml
undefinedCloudFormation: ECS Cluster with Fargate
CloudFormation: 带Fargate的ECS集群
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: production-cluster
ClusterSettings:
- Name: containerInsights
Value: enabled
Tags:
- Key: Environment
Value: Production
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: web-app
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: 512
Memory: 1024
ExecutionRoleArn: !GetAtt ECSExecutionRole.Arn
TaskRoleArn: !GetAtt ECSTaskRole.Arn
ContainerDefinitions:
- Name: web-container
Image: nginx:latest
PortMappings:
- ContainerPort: 80
Protocol: tcp
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref CloudWatchLogsGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: web-app
Environment:
- Name: ENVIRONMENT
Value: production
HealthCheck:
Command:
- CMD-SHELL
- curl -f http://localhost/ || exit 1
Interval: 30
Timeout: 5
Retries: 3
StartPeriod: 60
ECSService:
Type: AWS::ECS::Service
DependsOn: LoadBalancerListener
Properties:
ServiceName: web-service
Cluster: !Ref ECSCluster
TaskDefinition: !Ref TaskDefinition
DesiredCount: 2
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref ECSSecurityGroup
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
LoadBalancers:
- ContainerName: web-container
ContainerPort: 80
TargetGroupArn: !Ref TargetGroup
HealthCheckGracePeriodSeconds: 60
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DeploymentCircuitBreaker:
Enable: true
Rollback: true
ECSExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
Policies:
- PolicyName: SecretsManagerAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: !Ref DatabaseSecret
ECSTaskRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: S3Access
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
Resource: !Sub '${S3Bucket.Arn}/*'
undefinedECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: production-cluster
ClusterSettings:
- Name: containerInsights
Value: enabled
Tags:
- Key: Environment
Value: Production
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: web-app
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: 512
Memory: 1024
ExecutionRoleArn: !GetAtt ECSExecutionRole.Arn
TaskRoleArn: !GetAtt ECSTaskRole.Arn
ContainerDefinitions:
- Name: web-container
Image: nginx:latest
PortMappings:
- ContainerPort: 80
Protocol: tcp
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref CloudWatchLogsGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: web-app
Environment:
- Name: ENVIRONMENT
Value: production
HealthCheck:
Command:
- CMD-SHELL
- curl -f http://localhost/ || exit 1
Interval: 30
Timeout: 5
Retries: 3
StartPeriod: 60
ECSService:
Type: AWS::ECS::Service
DependsOn: LoadBalancerListener
Properties:
ServiceName: web-service
Cluster: !Ref ECSCluster
TaskDefinition: !Ref TaskDefinition
DesiredCount: 2
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref ECSSecurityGroup
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
LoadBalancers:
- ContainerName: web-container
ContainerPort: 80
TargetGroupArn: !Ref TargetGroup
HealthCheckGracePeriodSeconds: 60
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DeploymentCircuitBreaker:
Enable: true
Rollback: true
ECSExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
Policies:
- PolicyName: SecretsManagerAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: !Ref DatabaseSecret
ECSTaskRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: S3Access
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
Resource: !Sub '${S3Bucket.Arn}/*'
undefinedStorage Services
存储服务
Amazon S3 (Simple Storage Service)
Amazon S3 (简单存储服务)
Object storage service offering scalability, data availability, security, and performance.
提供可扩展性、数据可用性、安全性和性能的对象存储服务。
S3 Bucket with Lifecycle Policy
带生命周期策略的S3存储桶
yaml
undefinedyaml
undefinedCloudFormation: S3 Bucket with comprehensive configuration
CloudFormation: 配置全面的S3存储桶
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 'production-data-${AWS::AccountId}'
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
VersioningConfiguration:
Status: Enabled
LifecycleConfiguration:
Rules:
- Id: TransitionToIA
Status: Enabled
Transitions:
- TransitionInDays: 30
StorageClass: STANDARD_IA
- TransitionInDays: 90
StorageClass: GLACIER
- TransitionInDays: 365
StorageClass: DEEP_ARCHIVE
ExpirationInDays: 2555
NoncurrentVersionTransitions:
- TransitionInDays: 30
StorageClass: STANDARD_IA
- TransitionInDays: 90
StorageClass: GLACIER
NoncurrentVersionExpirationInDays: 365
- Id: DeleteIncompleteMultipartUploads
Status: Enabled
AbortIncompleteMultipartUpload:
DaysAfterInitiation: 7
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
LoggingConfiguration:
DestinationBucketName: !Ref LoggingBucket
LogFilePrefix: s3-access-logs/
NotificationConfiguration:
LambdaConfigurations:
- Event: s3:ObjectCreated:*
Function: !GetAtt ProcessingLambda.Arn
Filter:
S3Key:
Rules:
- Name: prefix
Value: uploads/
- Name: suffix
Value: .jpg
Tags:
- Key: Environment
Value: Production
S3BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref S3Bucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: EnforceTLSRequestsOnly
Effect: Deny
Principal: ''
Action: 's3:'
Resource:
- !GetAtt S3Bucket.Arn
- !Sub '${S3Bucket.Arn}/'
Condition:
Bool:
'aws:SecureTransport': false
- Sid: DenyUnencryptedObjectUploads
Effect: Deny
Principal: ''
Action: 's3:PutObject'
Resource: !Sub '${S3Bucket.Arn}/*'
Condition:
StringNotEquals:
's3:x-amz-server-side-encryption': AES256
undefinedS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 'production-data-${AWS::AccountId}'
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
VersioningConfiguration:
Status: Enabled
LifecycleConfiguration:
Rules:
- Id: TransitionToIA
Status: Enabled
Transitions:
- TransitionInDays: 30
StorageClass: STANDARD_IA
- TransitionInDays: 90
StorageClass: GLACIER
- TransitionInDays: 365
StorageClass: DEEP_ARCHIVE
ExpirationInDays: 2555
NoncurrentVersionTransitions:
- TransitionInDays: 30
StorageClass: STANDARD_IA
- TransitionInDays: 90
StorageClass: GLACIER
NoncurrentVersionExpirationInDays: 365
- Id: DeleteIncompleteMultipartUploads
Status: Enabled
AbortIncompleteMultipartUpload:
DaysAfterInitiation: 7
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
LoggingConfiguration:
DestinationBucketName: !Ref LoggingBucket
LogFilePrefix: s3-access-logs/
NotificationConfiguration:
LambdaConfigurations:
- Event: s3:ObjectCreated:*
Function: !GetAtt ProcessingLambda.Arn
Filter:
S3Key:
Rules:
- Name: prefix
Value: uploads/
- Name: suffix
Value: .jpg
Tags:
- Key: Environment
Value: Production
S3BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref S3Bucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: EnforceTLSRequestsOnly
Effect: Deny
Principal: ''
Action: 's3:'
Resource:
- !GetAtt S3Bucket.Arn
- !Sub '${S3Bucket.Arn}/'
Condition:
Bool:
'aws:SecureTransport': false
- Sid: DenyUnencryptedObjectUploads
Effect: Deny
Principal: ''
Action: 's3:PutObject'
Resource: !Sub '${S3Bucket.Arn}/*'
Condition:
StringNotEquals:
's3:x-amz-server-side-encryption': AES256
undefinedS3 CLI Operations
S3 CLI操作
bash
undefinedbash
undefinedUpload file with server-side encryption
上传文件并启用服务端加密
aws s3 cp myfile.txt s3://my-bucket/
--server-side-encryption AES256
--metadata '{"project":"webapp","environment":"production"}'
--server-side-encryption AES256
--metadata '{"project":"webapp","environment":"production"}'
aws s3 cp myfile.txt s3://my-bucket/
--server-side-encryption AES256
--metadata '{"project":"webapp","environment":"production"}'
--server-side-encryption AES256
--metadata '{"project":"webapp","environment":"production"}'
Sync directory with S3 bucket
同步本地目录到S3存储桶
aws s3 sync ./local-dir s3://my-bucket/backup/
--delete
--storage-class STANDARD_IA
--delete
--storage-class STANDARD_IA
aws s3 sync ./local-dir s3://my-bucket/backup/
--delete
--storage-class STANDARD_IA
--delete
--storage-class STANDARD_IA
Create presigned URL for temporary access
创建临时访问的预签名URL
aws s3 presign s3://my-bucket/private-file.pdf
--expires-in 3600
--expires-in 3600
aws s3 presign s3://my-bucket/private-file.pdf
--expires-in 3600
--expires-in 3600
List objects with specific prefix
列出带特定前缀的对象
aws s3api list-objects-v2
--bucket my-bucket
--prefix "uploads/2024/"
--query 'Contents[?Size >].[Key,Size,LastModified]'
--output table
--bucket my-bucket
--prefix "uploads/2024/"
--query 'Contents[?Size >
1048576--output table
aws s3api list-objects-v2
--bucket my-bucket
--prefix "uploads/2024/"
--query 'Contents[?Size >].[Key,Size,LastModified]'
--output table
--bucket my-bucket
--prefix "uploads/2024/"
--query 'Contents[?Size >
1048576--output table
Enable versioning
启用版本控制
aws s3api put-bucket-versioning
--bucket my-bucket
--versioning-configuration Status=Enabled
--bucket my-bucket
--versioning-configuration Status=Enabled
aws s3api put-bucket-versioning
--bucket my-bucket
--versioning-configuration Status=Enabled
--bucket my-bucket
--versioning-configuration Status=Enabled
Configure bucket lifecycle
配置存储桶生命周期
aws s3api put-bucket-lifecycle-configuration
--bucket my-bucket
--lifecycle-configuration file://lifecycle.json
--bucket my-bucket
--lifecycle-configuration file://lifecycle.json
undefinedaws s3api put-bucket-lifecycle-configuration
--bucket my-bucket
--lifecycle-configuration file://lifecycle.json
--bucket my-bucket
--lifecycle-configuration file://lifecycle.json
undefinedAmazon EBS (Elastic Block Store)
Amazon EBS (弹性块存储)
Block storage volumes for EC2 instances.
用于EC2实例的块存储卷。
EBS Volume with Snapshots
带快照的EBS卷
yaml
undefinedyaml
undefinedCloudFormation: EBS Volume with automated snapshots
CloudFormation: 带自动快照的EBS卷
DataVolume:
Type: AWS::EC2::Volume
Properties:
Size: 100
VolumeType: gp3
Iops: 3000
Throughput: 125
Encrypted: true
KmsKeyId: !Ref KMSKey
AvailabilityZone: !GetAtt EC2Instance.AvailabilityZone
Tags:
- Key: Name
Value: DataVolume
- Key: SnapshotSchedule
Value: daily
VolumeAttachment:
Type: AWS::EC2::VolumeAttachment
Properties:
Device: /dev/sdf
InstanceId: !Ref EC2Instance
VolumeId: !Ref DataVolume
```bashDataVolume:
Type: AWS::EC2::Volume
Properties:
Size: 100
VolumeType: gp3
Iops: 3000
Throughput: 125
Encrypted: true
KmsKeyId: !Ref KMSKey
AvailabilityZone: !GetAtt EC2Instance.AvailabilityZone
Tags:
- Key: Name
Value: DataVolume
- Key: SnapshotSchedule
Value: daily
VolumeAttachment:
Type: AWS::EC2::VolumeAttachment
Properties:
Device: /dev/sdf
InstanceId: !Ref EC2Instance
VolumeId: !Ref DataVolume
```bashCreate EBS snapshot
创建EBS快照
aws ec2 create-snapshot
--volume-id vol-1234567890abcdef0
--description "Daily backup - $(date +%Y-%m-%d)"
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=DailyBackup}]'
--volume-id vol-1234567890abcdef0
--description "Daily backup - $(date +%Y-%m-%d)"
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=DailyBackup}]'
aws ec2 create-snapshot
--volume-id vol-1234567890abcdef0
--description "Daily backup - $(date +%Y-%m-%d)"
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=DailyBackup}]'
--volume-id vol-1234567890abcdef0
--description "Daily backup - $(date +%Y-%m-%d)"
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=DailyBackup}]'
Copy snapshot to another region
将快照复制到另一个区域
aws ec2 copy-snapshot
--source-region us-east-1
--source-snapshot-id snap-1234567890abcdef0
--destination-region us-west-2
--description "DR copy"
--source-region us-east-1
--source-snapshot-id snap-1234567890abcdef0
--destination-region us-west-2
--description "DR copy"
aws ec2 copy-snapshot
--source-region us-east-1
--source-snapshot-id snap-1234567890abcdef0
--destination-region us-west-2
--description "DR copy"
--source-region us-east-1
--source-snapshot-id snap-1234567890abcdef0
--destination-region us-west-2
--description "DR copy"
Create volume from snapshot
从快照创建卷
aws ec2 create-volume
--snapshot-id snap-1234567890abcdef0
--availability-zone us-east-1a
--volume-type gp3
--iops 3000
--snapshot-id snap-1234567890abcdef0
--availability-zone us-east-1a
--volume-type gp3
--iops 3000
undefinedaws ec2 create-volume
--snapshot-id snap-1234567890abcdef0
--availability-zone us-east-1a
--volume-type gp3
--iops 3000
--snapshot-id snap-1234567890abcdef0
--availability-zone us-east-1a
--volume-type gp3
--iops 3000
undefinedAmazon EFS (Elastic File System)
Amazon EFS (弹性文件系统)
Managed NFS file system for EC2 instances.
yaml
undefined用于EC2实例的托管NFS文件系统。
yaml
undefinedCloudFormation: EFS File System
CloudFormation: EFS文件系统
EFSFileSystem:
Type: AWS::EFS::FileSystem
Properties:
Encrypted: true
KmsKeyId: !Ref KMSKey
PerformanceMode: generalPurpose
ThroughputMode: bursting
LifecyclePolicies:
- TransitionToIA: AFTER_30_DAYS
- TransitionToPrimaryStorageClass: AFTER_1_ACCESS
FileSystemTags:
- Key: Name
Value: SharedStorage
MountTargetSubnet1:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref EFSFileSystem
SubnetId: !Ref PrivateSubnet1
SecurityGroups:
- !Ref EFSSecurityGroup
MountTargetSubnet2:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref EFSFileSystem
SubnetId: !Ref PrivateSubnet2
SecurityGroups:
- !Ref EFSSecurityGroup
EFSSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for EFS mount targets
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 2049
ToPort: 2049
SourceSecurityGroupId: !Ref EC2SecurityGroup
undefinedEFSFileSystem:
Type: AWS::EFS::FileSystem
Properties:
Encrypted: true
KmsKeyId: !Ref KMSKey
PerformanceMode: generalPurpose
ThroughputMode: bursting
LifecyclePolicies:
- TransitionToIA: AFTER_30_DAYS
- TransitionToPrimaryStorageClass: AFTER_1_ACCESS
FileSystemTags:
- Key: Name
Value: SharedStorage
MountTargetSubnet1:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref EFSFileSystem
SubnetId: !Ref PrivateSubnet1
SecurityGroups:
- !Ref EFSSecurityGroup
MountTargetSubnet2:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref EFSFileSystem
SubnetId: !Ref PrivateSubnet2
SecurityGroups:
- !Ref EFSSecurityGroup
EFSSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: EFS挂载目标安全组
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 2049
ToPort: 2049
SourceSecurityGroupId: !Ref EC2SecurityGroup
undefinedDatabase Services
数据库服务
Amazon RDS (Relational Database Service)
Amazon RDS (关系型数据库服务)
Managed relational database service supporting multiple engines.
支持多种引擎的托管关系型数据库服务。
RDS Multi-AZ with Read Replicas
带只读副本的多可用区RDS
yaml
undefinedyaml
undefinedCloudFormation: RDS PostgreSQL with Multi-AZ
CloudFormation: 多可用区PostgreSQL RDS
DBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupName: rds-subnet-group
DBSubnetGroupDescription: Subnet group for RDS instances
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
- !Ref PrivateSubnet3
Tags:
- Key: Name
Value: RDS-SubnetGroup
DBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for RDS database
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 5432
ToPort: 5432
SourceSecurityGroupId: !Ref AppSecurityGroup
Tags:
- Key: Name
Value: RDS-SecurityGroup
RDSInstance:
Type: AWS::RDS::DBInstance
DeletionPolicy: Snapshot
Properties:
DBInstanceIdentifier: production-db
DBInstanceClass: db.r6g.xlarge
Engine: postgres
EngineVersion: '15.3'
MasterUsername: !Sub '{{resolve:secretsmanager:${DBSecret}:SecretString:username}}'
MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBSecret}:SecretString:password}}'
AllocatedStorage: 100
MaxAllocatedStorage: 1000
StorageType: gp3
Iops: 3000
StorageEncrypted: true
KmsKeyId: !Ref KMSKey
MultiAZ: true
DBSubnetGroupName: !Ref DBSubnetGroup
VPCSecurityGroups:
- !Ref DBSecurityGroup
BackupRetentionPeriod: 30
PreferredBackupWindow: '03:00-04:00'
PreferredMaintenanceWindow: 'sun:04:00-sun:05:00'
EnableCloudwatchLogsExports:
- postgresql
- upgrade
DeletionProtection: true
EnableIAMDatabaseAuthentication: true
MonitoringInterval: 60
MonitoringRoleArn: !GetAtt MonitoringRole.Arn
EnablePerformanceInsights: true
PerformanceInsightsRetentionPeriod: 7
PerformanceInsightsKMSKeyId: !Ref KMSKey
Tags:
- Key: Environment
Value: Production
ReadReplica1:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: production-db-replica-1
SourceDBInstanceIdentifier: !Ref RDSInstance
DBInstanceClass: db.r6g.large
PubliclyAccessible: false
Tags:
- Key: Name
Value: ReadReplica1
- Key: Purpose
Value: Analytics
DBSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: rds-database-credentials
Description: RDS database master credentials
GenerateSecretString:
SecretStringTemplate: '{"username": "dbadmin"}'
GenerateStringKey: password
PasswordLength: 32
ExcludeCharacters: '"@/'
RequireEachIncludedType: true
SecretRDSAttachment:
Type: AWS::SecretsManager::SecretTargetAttachment
Properties:
SecretId: !Ref DBSecret
TargetId: !Ref RDSInstance
TargetType: AWS::RDS::DBInstance
undefinedDBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupName: rds-subnet-group
DBSubnetGroupDescription: RDS实例子网组
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
- !Ref PrivateSubnet3
Tags:
- Key: Name
Value: RDS-SubnetGroup
DBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: RDS数据库安全组
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 5432
ToPort: 5432
SourceSecurityGroupId: !Ref AppSecurityGroup
Tags:
- Key: Name
Value: RDS-SecurityGroup
RDSInstance:
Type: AWS::RDS::DBInstance
DeletionPolicy: Snapshot
Properties:
DBInstanceIdentifier: production-db
DBInstanceClass: db.r6g.xlarge
Engine: postgres
EngineVersion: '15.3'
MasterUsername: !Sub '{{resolve:secretsmanager:${DBSecret}:SecretString:username}}'
MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBSecret}:SecretString:password}}'
AllocatedStorage: 100
MaxAllocatedStorage: 1000
StorageType: gp3
Iops: 3000
StorageEncrypted: true
KmsKeyId: !Ref KMSKey
MultiAZ: true
DBSubnetGroupName: !Ref DBSubnetGroup
VPCSecurityGroups:
- !Ref DBSecurityGroup
BackupRetentionPeriod: 30
PreferredBackupWindow: '03:00-04:00'
PreferredMaintenanceWindow: 'sun:04:00-sun:05:00'
EnableCloudwatchLogsExports:
- postgresql
- upgrade
DeletionProtection: true
EnableIAMDatabaseAuthentication: true
MonitoringInterval: 60
MonitoringRoleArn: !GetAtt MonitoringRole.Arn
EnablePerformanceInsights: true
PerformanceInsightsRetentionPeriod: 7
PerformanceInsightsKMSKeyId: !Ref KMSKey
Tags:
- Key: Environment
Value: Production
ReadReplica1:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: production-db-replica-1
SourceDBInstanceIdentifier: !Ref RDSInstance
DBInstanceClass: db.r6g.large
PubliclyAccessible: false
Tags:
- Key: Name
Value: ReadReplica1
- Key: Purpose
Value: Analytics
DBSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: rds-database-credentials
Description: RDS数据库主凭证
GenerateSecretString:
SecretStringTemplate: '{"username": "dbadmin"}'
GenerateStringKey: password
PasswordLength: 32
ExcludeCharacters: '"@/'
RequireEachIncludedType: true
SecretRDSAttachment:
Type: AWS::SecretsManager::SecretTargetAttachment
Properties:
SecretId: !Ref DBSecret
TargetId: !Ref RDSInstance
TargetType: AWS::RDS::DBInstance
undefinedAmazon DynamoDB
Amazon DynamoDB
Fully managed NoSQL database service.
全托管NoSQL数据库服务。
DynamoDB Table with GSI and Streams
带全局二级索引和流的DynamoDB表
yaml
undefinedyaml
undefinedCloudFormation: DynamoDB Table
CloudFormation: DynamoDB表
DynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: Users
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
- AttributeName: email
AttributeType: S
- AttributeName: createdAt
AttributeType: N
- AttributeName: status
AttributeType: S
KeySchema:
- AttributeName: userId
KeyType: HASH
GlobalSecondaryIndexes:
- IndexName: EmailIndex
KeySchema:
- AttributeName: email
KeyType: HASH
Projection:
ProjectionType: ALL
- IndexName: StatusIndex
KeySchema:
- AttributeName: status
KeyType: HASH
- AttributeName: createdAt
KeyType: RANGE
Projection:
ProjectionType: ALL
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true
SSESpecification:
SSEEnabled: true
SSEType: KMS
KMSMasterKeyId: !Ref KMSKey
Tags:
- Key: Environment
Value: Production
DynamoDBStreamProcessor:
Type: AWS::Lambda::Function
Properties:
FunctionName: DynamoDBStreamProcessor
Runtime: python3.11
Handler: index.lambda_handler
Role: !GetAtt StreamProcessorRole.Arn
Code:
ZipFile: |
import json
def lambda_handler(event, context):
for record in event['Records']:
if record['eventName'] == 'INSERT':
new_image = record['dynamodb']['NewImage']
print(f"New user created: {json.dumps(new_image)}")
elif record['eventName'] == 'MODIFY':
print(f"User modified")
elif record['eventName'] == 'REMOVE':
print(f"User deleted")
return {'statusCode': 200}EventSourceMapping:
Type: AWS::Lambda::EventSourceMapping
Properties:
EventSourceArn: !GetAtt DynamoDBTable.StreamArn
FunctionName: !Ref DynamoDBStreamProcessor
StartingPosition: LATEST
BatchSize: 100
MaximumBatchingWindowInSeconds: 10
undefinedDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: Users
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
- AttributeName: email
AttributeType: S
- AttributeName: createdAt
AttributeType: N
- AttributeName: status
AttributeType: S
KeySchema:
- AttributeName: userId
KeyType: HASH
GlobalSecondaryIndexes:
- IndexName: EmailIndex
KeySchema:
- AttributeName: email
KeyType: HASH
Projection:
ProjectionType: ALL
- IndexName: StatusIndex
KeySchema:
- AttributeName: status
KeyType: HASH
- AttributeName: createdAt
KeyType: RANGE
Projection:
ProjectionType: ALL
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true
SSESpecification:
SSEEnabled: true
SSEType: KMS
KMSMasterKeyId: !Ref KMSKey
Tags:
- Key: Environment
Value: Production
DynamoDBStreamProcessor:
Type: AWS::Lambda::Function
Properties:
FunctionName: DynamoDBStreamProcessor
Runtime: python3.11
Handler: index.lambda_handler
Role: !GetAtt StreamProcessorRole.Arn
Code:
ZipFile: |
import json
def lambda_handler(event, context):
for record in event['Records']:
if record['eventName'] == 'INSERT':
new_image = record['dynamodb']['NewImage']
print(f"New user created: {json.dumps(new_image)}")
elif record['eventName'] == 'MODIFY':
print(f"User modified")
elif record['eventName'] == 'REMOVE':
print(f"User deleted")
return {'statusCode': 200}EventSourceMapping:
Type: AWS::Lambda::EventSourceMapping
Properties:
EventSourceArn: !GetAtt DynamoDBTable.StreamArn
FunctionName: !Ref DynamoDBStreamProcessor
StartingPosition: LATEST
BatchSize: 100
MaximumBatchingWindowInSeconds: 10
undefinedDynamoDB Operations with Python
Python操作DynamoDB
python
undefinedpython
undefinedPython SDK (boto3) for DynamoDB operations
用于DynamoDB操作的Python SDK (boto3)
import boto3
from boto3.dynamodb.conditions import Key, Attr
from decimal import Decimal
import json
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Users')
import boto3
from boto3.dynamodb.conditions import Key, Attr
from decimal import Decimal
import json
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Users')
Put item
插入数据
def create_user(user_id, email, name):
response = table.put_item(
Item={
'userId': user_id,
'email': email,
'name': name,
'createdAt': int(time.time()),
'status': 'active',
'metadata': {
'loginCount': 0,
'lastLogin': None
}
},
ConditionExpression='attribute_not_exists(userId)'
)
return response
def create_user(user_id, email, name):
response = table.put_item(
Item={
'userId': user_id,
'email': email,
'name': name,
'createdAt': int(time.time()),
'status': 'active',
'metadata': {
'loginCount': 0,
'lastLogin': None
}
},
ConditionExpression='attribute_not_exists(userId)'
)
return response
Get item
获取数据
def get_user(user_id):
response = table.get_item(
Key={'userId': user_id},
ProjectionExpression='userId, email, #n, #s',
ExpressionAttributeNames={
'#n': 'name',
'#s': 'status'
}
)
return response.get('Item')
def get_user(user_id):
response = table.get_item(
Key={'userId': user_id},
ProjectionExpression='userId, email, #n, #s',
ExpressionAttributeNames={
'#n': 'name',
'#s': 'status'
}
)
return response.get('Item')
Query with GSI
使用全局二级索引查询
def get_user_by_email(email):
response = table.query(
IndexName='EmailIndex',
KeyConditionExpression=Key('email').eq(email)
)
return response.get('Items', [])
def get_user_by_email(email):
response = table.query(
IndexName='EmailIndex',
KeyConditionExpression=Key('email').eq(email)
)
return response.get('Items', [])
Update item
更新数据
def update_user_status(user_id, new_status):
response = table.update_item(
Key={'userId': user_id},
UpdateExpression='SET #s = :status, updatedAt = :timestamp',
ExpressionAttributeNames={
'#s': 'status'
},
ExpressionAttributeValues={
':status': new_status,
':timestamp': int(time.time())
},
ReturnValues='ALL_NEW'
)
return response.get('Attributes')
def update_user_status(user_id, new_status):
response = table.update_item(
Key={'userId': user_id},
UpdateExpression='SET #s = :status, updatedAt = :timestamp',
ExpressionAttributeNames={
'#s': 'status'
},
ExpressionAttributeValues={
':status': new_status,
':timestamp': int(time.time())
},
ReturnValues='ALL_NEW'
)
return response.get('Attributes')
Batch write
批量写入
def batch_create_users(users):
with table.batch_writer() as batch:
for user in users:
batch.put_item(Item=user)
def batch_create_users(users):
with table.batch_writer() as batch:
for user in users:
batch.put_item(Item=user)
Scan with filter
带过滤条件的扫描
def get_active_users():
response = table.scan(
FilterExpression=Attr('status').eq('active')
)
return response.get('Items', [])
def get_active_users():
response = table.scan(
FilterExpression=Attr('status').eq('active')
)
return response.get('Items', [])
Transaction write
事务写入
def transfer_credits(from_user_id, to_user_id, amount):
client = boto3.client('dynamodb')
response = client.transact_write_items(
TransactItems=[
{
'Update': {
'TableName': 'Users',
'Key': {'userId': {'S': from_user_id}},
'UpdateExpression': 'SET credits = credits - :amount',
'ExpressionAttributeValues': {':amount': {'N': str(amount)}},
'ConditionExpression': 'credits >= :amount'
}
},
{
'Update': {
'TableName': 'Users',
'Key': {'userId': {'S': to_user_id}},
'UpdateExpression': 'SET credits = credits + :amount',
'ExpressionAttributeValues': {':amount': {'N': str(amount)}}
}
}
]
)
return response
undefineddef transfer_credits(from_user_id, to_user_id, amount):
client = boto3.client('dynamodb')
response = client.transact_write_items(
TransactItems=[
{
'Update': {
'TableName': 'Users',
'Key': {'userId': {'S': from_user_id}},
'UpdateExpression': 'SET credits = credits - :amount',
'ExpressionAttributeValues': {':amount': {'N': str(amount)}},
'ConditionExpression': 'credits >= :amount'
}
},
{
'Update': {
'TableName': 'Users',
'Key': {'userId': {'S': to_user_id}},
'UpdateExpression': 'SET credits = credits + :amount',
'ExpressionAttributeValues': {':amount': {'N': str(amount)}}
}
}
]
)
return response
undefinedAmazon Aurora
Amazon Aurora
MySQL and PostgreSQL-compatible relational database with enhanced performance.
yaml
undefined兼容MySQL和PostgreSQL的高性能关系型数据库。
yaml
undefinedCloudFormation: Aurora PostgreSQL Cluster
CloudFormation: Aurora PostgreSQL集群
AuroraCluster:
Type: AWS::RDS::DBCluster
Properties:
DBClusterIdentifier: production-aurora-cluster
Engine: aurora-postgresql
EngineVersion: '15.3'
MasterUsername: !Sub '{{resolve:secretsmanager:${AuroraSecret}:SecretString:username}}'
MasterUserPassword: !Sub '{{resolve:secretsmanager:${AuroraSecret}:SecretString:password}}'
DatabaseName: productiondb
DBSubnetGroupName: !Ref DBSubnetGroup
VpcSecurityGroupIds:
- !Ref DBSecurityGroup
BackupRetentionPeriod: 35
PreferredBackupWindow: '03:00-04:00'
PreferredMaintenanceWindow: 'sun:04:00-sun:05:00'
StorageEncrypted: true
KmsKeyId: !Ref KMSKey
EnableCloudwatchLogsExports:
- postgresql
DeletionProtection: true
EnableIAMDatabaseAuthentication: true
Tags:
- Key: Environment
Value: Production
AuroraInstance1:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: aurora-instance-1
DBClusterIdentifier: !Ref AuroraCluster
DBInstanceClass: db.r6g.xlarge
Engine: aurora-postgresql
PubliclyAccessible: false
EnablePerformanceInsights: true
PerformanceInsightsRetentionPeriod: 7
MonitoringInterval: 60
MonitoringRoleArn: !GetAtt MonitoringRole.Arn
AuroraInstance2:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: aurora-instance-2
DBClusterIdentifier: !Ref AuroraCluster
DBInstanceClass: db.r6g.large
Engine: aurora-postgresql
PubliclyAccessible: false
undefinedAuroraCluster:
Type: AWS::RDS::DBCluster
Properties:
DBClusterIdentifier: production-aurora-cluster
Engine: aurora-postgresql
EngineVersion: '15.3'
MasterUsername: !Sub '{{resolve:secretsmanager:${AuroraSecret}:SecretString:username}}'
MasterUserPassword: !Sub '{{resolve:secretsmanager:${AuroraSecret}:SecretString:password}}'
DatabaseName: productiondb
DBSubnetGroupName: !Ref DBSubnetGroup
VpcSecurityGroupIds:
- !Ref DBSecurityGroup
BackupRetentionPeriod: 35
PreferredBackupWindow: '03:00-04:00'
PreferredMaintenanceWindow: 'sun:04:00-sun:05:00'
StorageEncrypted: true
KmsKeyId: !Ref KMSKey
EnableCloudwatchLogsExports:
- postgresql
DeletionProtection: true
EnableIAMDatabaseAuthentication: true
Tags:
- Key: Environment
Value: Production
AuroraInstance1:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: aurora-instance-1
DBClusterIdentifier: !Ref AuroraCluster
DBInstanceClass: db.r6g.xlarge
Engine: aurora-postgresql
PubliclyAccessible: false
EnablePerformanceInsights: true
PerformanceInsightsRetentionPeriod: 7
MonitoringInterval: 60
MonitoringRoleArn: !GetAtt MonitoringRole.Arn
AuroraInstance2:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: aurora-instance-2
DBClusterIdentifier: !Ref AuroraCluster
DBInstanceClass: db.r6g.large
Engine: aurora-postgresql
PubliclyAccessible: false
undefinedNetworking and Content Delivery
网络与内容分发
Amazon VPC (Virtual Private Cloud)
Amazon VPC (虚拟私有云)
Isolated cloud resources in a virtual network.
在虚拟网络中隔离云资源。
Production VPC with Public and Private Subnets
带公网和私有子网的生产级VPC
yaml
undefinedyaml
undefinedCloudFormation: Complete VPC Setup
CloudFormation: 完整的VPC配置
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: Production-VPC
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: Production-VPC
Internet Gateway
互联网网关
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: Production-IGW
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: Production-IGW
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
Public Subnets
公网子网
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: Public-Subnet-1
- Key: Type
Value: Public
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: !Select [1, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: Public-Subnet-2
- Key: Type
Value: Public
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: Public-Subnet-1
- Key: Type
Value: Public
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: !Select [1, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: Public-Subnet-2
- Key: Type
Value: Public
Private Subnets
私有子网
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.11.0/24
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: Private-Subnet-1
- Key: Type
Value: Private
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.12.0/24
AvailabilityZone: !Select [1, !GetAZs '']
Tags:
- Key: Name
Value: Private-Subnet-2
- Key: Type
Value: Private
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.11.0/24
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: Private-Subnet-1
- Key: Type
Value: Private
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.12.0/24
AvailabilityZone: !Select [1, !GetAZs '']
Tags:
- Key: Name
Value: Private-Subnet-2
- Key: Type
Value: Private
NAT Gateways
NAT网关
NATGateway1EIP:
Type: AWS::EC2::EIP
DependsOn: AttachGateway
Properties:
Domain: vpc
Tags:
- Key: Name
Value: NAT-Gateway-1-EIP
NATGateway1:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NATGateway1EIP.AllocationId
SubnetId: !Ref PublicSubnet1
Tags:
- Key: Name
Value: NAT-Gateway-1
NATGateway2EIP:
Type: AWS::EC2::EIP
DependsOn: AttachGateway
Properties:
Domain: vpc
Tags:
- Key: Name
Value: NAT-Gateway-2-EIP
NATGateway2:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NATGateway2EIP.AllocationId
SubnetId: !Ref PublicSubnet2
Tags:
- Key: Name
Value: NAT-Gateway-2
NATGateway1EIP:
Type: AWS::EC2::EIP
DependsOn: AttachGateway
Properties:
Domain: vpc
Tags:
- Key: Name
Value: NAT-Gateway-1-EIP
NATGateway1:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NATGateway1EIP.AllocationId
SubnetId: !Ref PublicSubnet1
Tags:
- Key: Name
Value: NAT-Gateway-1
NATGateway2EIP:
Type: AWS::EC2::EIP
DependsOn: AttachGateway
Properties:
Domain: vpc
Tags:
- Key: Name
Value: NAT-Gateway-2-EIP
NATGateway2:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NATGateway2EIP.AllocationId
SubnetId: !Ref PublicSubnet2
Tags:
- Key: Name
Value: NAT-Gateway-2
Route Tables
路由表
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Public-RouteTable
PublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Private-RouteTable-1
PrivateRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway1
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet1
RouteTableId: !Ref PrivateRouteTable1
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Private-RouteTable-2
PrivateRoute2:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable2
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway2
PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref PrivateRouteTable2
undefinedPublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Public-RouteTable
PublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Private-RouteTable-1
PrivateRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway1
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet1
RouteTableId: !Ref PrivateRouteTable1
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Private-RouteTable-2
PrivateRoute2:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable2
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway2
PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref PrivateRouteTable2
undefinedVPC Endpoints
VPC终端节点
yaml
undefinedyaml
undefinedCloudFormation: VPC Endpoints for AWS Services
CloudFormation: AWS服务的VPC终端节点
S3VPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3'
RouteTableIds:
- !Ref PrivateRouteTable1
- !Ref PrivateRouteTable2
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: ''
Action:
- 's3:GetObject'
- 's3:PutObject'
Resource: ''
DynamoDBVPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.dynamodb'
RouteTableIds:
- !Ref PrivateRouteTable1
- !Ref PrivateRouteTable2
SecretsManagerVPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
PrivateDnsEnabled: true
VpcId: !Ref VPC
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.secretsmanager'
SecurityGroupIds:
- !Ref VPCEndpointSecurityGroup
SSMVPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
PrivateDnsEnabled: true
VpcId: !Ref VPC
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssm'
SecurityGroupIds:
- !Ref VPCEndpointSecurityGroup
undefinedS3VPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3'
RouteTableIds:
- !Ref PrivateRouteTable1
- !Ref PrivateRouteTable2
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: ''
Action:
- 's3:GetObject'
- 's3:PutObject'
Resource: ''
DynamoDBVPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.dynamodb'
RouteTableIds:
- !Ref PrivateRouteTable1
- !Ref PrivateRouteTable2
SecretsManagerVPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
PrivateDnsEnabled: true
VpcId: !Ref VPC
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.secretsmanager'
SecurityGroupIds:
- !Ref VPCEndpointSecurityGroup
SSMVPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
PrivateDnsEnabled: true
VpcId: !Ref VPC
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssm'
SecurityGroupIds:
- !Ref VPCEndpointSecurityGroup
undefinedApplication Load Balancer
应用负载均衡器
yaml
undefinedyaml
undefinedCloudFormation: Application Load Balancer
CloudFormation: 应用负载均衡器
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: production-alb
Type: application
Scheme: internet-facing
IpAddressType: ipv4
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
SecurityGroups:
- !Ref ALBSecurityGroup
Tags:
- Key: Name
Value: Production-ALB
ALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref TargetGroup
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: ELBSecurityPolicy-TLS-1-2-2017-01
Certificates:
- CertificateArn: !Ref SSLCertificate
ALBListenerHTTP:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: redirect
RedirectConfig:
Protocol: HTTPS
Port: 443
StatusCode: HTTP_301
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: web-servers
Port: 80
Protocol: HTTP
VpcId: !Ref VPC
HealthCheckEnabled: true
HealthCheckPath: /health
HealthCheckProtocol: HTTP
HealthCheckIntervalSeconds: 30
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3
Matcher:
HttpCode: 200
TargetType: instance
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 30
- Key: stickiness.enabled
Value: true
- Key: stickiness.type
Value: lb_cookie
- Key: stickiness.lb_cookie.duration_seconds
Value: 86400
undefinedApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: production-alb
Type: application
Scheme: internet-facing
IpAddressType: ipv4
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
SecurityGroups:
- !Ref ALBSecurityGroup
Tags:
- Key: Name
Value: Production-ALB
ALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref TargetGroup
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: ELBSecurityPolicy-TLS-1-2-2017-01
Certificates:
- CertificateArn: !Ref SSLCertificate
ALBListenerHTTP:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: redirect
RedirectConfig:
Protocol: HTTPS
Port: 443
StatusCode: HTTP_301
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: web-servers
Port: 80
Protocol: HTTP
VpcId: !Ref VPC
HealthCheckEnabled: true
HealthCheckPath: /health
HealthCheckProtocol: HTTP
HealthCheckIntervalSeconds: 30
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3
Matcher:
HttpCode: 200
TargetType: instance
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 30
- Key: stickiness.enabled
Value: true
- Key: stickiness.type
Value: lb_cookie
- Key: stickiness.lb_cookie.duration_seconds
Value: 86400
undefinedAmazon CloudFront
Amazon CloudFront
Content delivery network (CDN) service.
yaml
undefined内容分发网络(CDN)服务。
yaml
undefinedCloudFormation: CloudFront Distribution
CloudFormation: CloudFront分发
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
Comment: Production CDN
DefaultRootObject: index.html
PriceClass: PriceClass_All
HttpVersion: http2and3
Origins:
- Id: S3Origin
DomainName: !GetAtt S3Bucket.RegionalDomainName
S3OriginConfig:
OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/${CloudFrontOAI}'
- Id: ALBOrigin
DomainName: !GetAtt ApplicationLoadBalancer.DNSName
CustomOriginConfig:
HTTPPort: 80
HTTPSPort: 443
OriginProtocolPolicy: https-only
OriginSSLProtocols:
- TLSv1.2
DefaultCacheBehavior:
TargetOriginId: S3Origin
ViewerProtocolPolicy: redirect-to-https
AllowedMethods:
- GET
- HEAD
- OPTIONS
CachedMethods:
- GET
- HEAD
Compress: true
CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6 # Managed-CachingOptimized
OriginRequestPolicyId: 88a5eaf4-2fd4-4709-b370-b4c650ea3fcf # Managed-CORS-S3Origin
CacheBehaviors:
- PathPattern: '/api/*'
TargetOriginId: ALBOrigin
ViewerProtocolPolicy: https-only
AllowedMethods:
- DELETE
- GET
- HEAD
- OPTIONS
- PATCH
- POST
- PUT
CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad # Managed-CachingDisabled
OriginRequestPolicyId: 216adef6-5c7f-47e4-b989-5492eafa07d3 # Managed-AllViewer
ViewerCertificate:
AcmCertificateArn: !Ref SSLCertificate
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.2_2021
Logging:
Bucket: !GetAtt LoggingBucket.DomainName
Prefix: cloudfront-logs/
IncludeCookies: false
CustomErrorResponses:
- ErrorCode: 403
ResponseCode: 404
ResponsePagePath: /404.html
- ErrorCode: 404
ResponseCode: 404
ResponsePagePath: /404.html
CloudFrontOAI:
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: OAI for S3 bucket access
undefinedCloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
Comment: Production CDN
DefaultRootObject: index.html
PriceClass: PriceClass_All
HttpVersion: http2and3
Origins:
- Id: S3Origin
DomainName: !GetAtt S3Bucket.RegionalDomainName
S3OriginConfig:
OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/${CloudFrontOAI}'
- Id: ALBOrigin
DomainName: !GetAtt ApplicationLoadBalancer.DNSName
CustomOriginConfig:
HTTPPort: 80
HTTPSPort: 443
OriginProtocolPolicy: https-only
OriginSSLProtocols:
- TLSv1.2
DefaultCacheBehavior:
TargetOriginId: S3Origin
ViewerProtocolPolicy: redirect-to-https
AllowedMethods:
- GET
- HEAD
- OPTIONS
CachedMethods:
- GET
- HEAD
Compress: true
CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6 # Managed-CachingOptimized
OriginRequestPolicyId: 88a5eaf4-2fd4-4709-b370-b4c650ea3fcf # Managed-CORS-S3Origin
CacheBehaviors:
- PathPattern: '/api/*'
TargetOriginId: ALBOrigin
ViewerProtocolPolicy: https-only
AllowedMethods:
- DELETE
- GET
- HEAD
- OPTIONS
- PATCH
- POST
- PUT
CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad # Managed-CachingDisabled
OriginRequestPolicyId: 216adef6-5c7f-47e4-b989-5492eafa07d3 # Managed-AllViewer
ViewerCertificate:
AcmCertificateArn: !Ref SSLCertificate
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.2_2021
Logging:
Bucket: !GetAtt LoggingBucket.DomainName
Prefix: cloudfront-logs/
IncludeCookies: false
CustomErrorResponses:
- ErrorCode: 403
ResponseCode: 404
ResponsePagePath: /404.html
- ErrorCode: 404
ResponseCode: 404
ResponsePagePath: /404.html
CloudFrontOAI:
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: 用于S3存储桶访问的OAI
undefinedSecurity, Identity, and Compliance
安全、身份与合规
AWS IAM (Identity and Access Management)
AWS IAM (身份与访问管理)
IAM Roles and Policies
IAM角色与策略
yaml
undefinedyaml
undefinedCloudFormation: IAM Role with least privilege
CloudFormation: 遵循最小权限原则的IAM角色
EC2InstanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: EC2-WebServer-Role
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Policies:
- PolicyName: S3BucketAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: ListBucket
Effect: Allow
Action:
- s3:ListBucket
Resource: !GetAtt S3Bucket.Arn
- Sid: GetPutObjects
Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
Resource: !Sub '${S3Bucket.Arn}/*'
- PolicyName: DynamoDBAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:Query
Resource: !GetAtt DynamoDBTable.Arn
Condition:
StringEquals:
'dynamodb:LeadingKeys':
- '${aws:username}'
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: EC2-WebServer-Profile
Roles:
- !Ref EC2InstanceRole
undefinedEC2InstanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: EC2-WebServer-Role
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Policies:
- PolicyName: S3BucketAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: ListBucket
Effect: Allow
Action:
- s3:ListBucket
Resource: !GetAtt S3Bucket.Arn
- Sid: GetPutObjects
Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
Resource: !Sub '${S3Bucket.Arn}/*'
- PolicyName: DynamoDBAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:Query
Resource: !GetAtt DynamoDBTable.Arn
Condition:
StringEquals:
'dynamodb:LeadingKeys':
- '${aws:username}'
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: EC2-WebServer-Profile
Roles:
- !Ref EC2InstanceRole
undefinedCross-Account Access Role
跨账号访问角色
yaml
undefinedyaml
undefinedCloudFormation: Cross-account IAM role
CloudFormation: 跨账号IAM角色
CrossAccountRole:
Type: AWS::IAM::Role
Properties:
RoleName: CrossAccountAccessRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${TrustedAccountId}:root'
Action: sts:AssumeRole
Condition:
StringEquals:
'sts:ExternalId': !Ref ExternalId
Policies:
- PolicyName: ReadOnlyAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:GetObject
- s3:ListBucket
Resource:
- !GetAtt S3Bucket.Arn
- !Sub '${S3Bucket.Arn}/*'
undefinedCrossAccountRole:
Type: AWS::IAM::Role
Properties:
RoleName: CrossAccountAccessRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${TrustedAccountId}:root'
Action: sts:AssumeRole
Condition:
StringEquals:
'sts:ExternalId': !Ref ExternalId
Policies:
- PolicyName: ReadOnlyAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:GetObject
- s3:ListBucket
Resource:
- !GetAtt S3Bucket.Arn
- !Sub '${S3Bucket.Arn}/*'
undefinedAWS KMS (Key Management Service)
AWS KMS (密钥管理服务)
yaml
undefinedyaml
undefinedCloudFormation: KMS Key with key policy
CloudFormation: 带密钥策略的KMS密钥
KMSKey:
Type: AWS::KMS::Key
Properties:
Description: Master encryption key for production resources
KeyPolicy:
Version: '2012-10-17'
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action: 'kms:'
Resource: ''
- Sid: Allow services to use the key
Effect: Allow
Principal:
Service:
- s3.amazonaws.com
- rds.amazonaws.com
- lambda.amazonaws.com
Action:
- 'kms:Decrypt'
- 'kms:GenerateDataKey'
Resource: ''
- Sid: Allow administrators to manage the key
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:role/Admin'
Action:
- 'kms:Create'
- 'kms:Describe*'
- 'kms:Enable*'
- 'kms:List*'
- 'kms:Put*'
- 'kms:Update*'
- 'kms:Revoke*'
- 'kms:Disable*'
- 'kms:Get*'
- 'kms:Delete*'
- 'kms:ScheduleKeyDeletion'
- 'kms:CancelKeyDeletion'
Resource: '*'
KMSKeyAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: alias/production-master-key
TargetKeyId: !Ref KMSKey
undefinedKMSKey:
Type: AWS::KMS::Key
Properties:
Description: 生产资源的主加密密钥
KeyPolicy:
Version: '2012-10-17'
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action: 'kms:'
Resource: ''
- Sid: Allow services to use the key
Effect: Allow
Principal:
Service:
- s3.amazonaws.com
- rds.amazonaws.com
- lambda.amazonaws.com
Action:
- 'kms:Decrypt'
- 'kms:GenerateDataKey'
Resource: ''
- Sid: Allow administrators to manage the key
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:role/Admin'
Action:
- 'kms:Create'
- 'kms:Describe*'
- 'kms:Enable*'
- 'kms:List*'
- 'kms:Put*'
- 'kms:Update*'
- 'kms:Revoke*'
- 'kms:Disable*'
- 'kms:Get*'
- 'kms:Delete*'
- 'kms:ScheduleKeyDeletion'
- 'kms:CancelKeyDeletion'
Resource: '*'
KMSKeyAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: alias/production-master-key
TargetKeyId: !Ref KMSKey
undefinedAWS CloudTrail
AWS CloudTrail
yaml
undefinedyaml
undefinedCloudFormation: CloudTrail for audit logging
CloudFormation: 用于审计日志的CloudTrail
CloudTrailBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 'cloudtrail-logs-${AWS::AccountId}'
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
LifecycleConfiguration:
Rules:
- Id: MoveToGlacier
Status: Enabled
Transitions:
- TransitionInDays: 90
StorageClass: GLACIER
ExpirationInDays: 2555
CloudTrailBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref CloudTrailBucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AWSCloudTrailAclCheck
Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Action: 's3:GetBucketAcl'
Resource: !GetAtt CloudTrailBucket.Arn
- Sid: AWSCloudTrailWrite
Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Action: 's3:PutObject'
Resource: !Sub '${CloudTrailBucket.Arn}/*'
Condition:
StringEquals:
's3:x-amz-acl': bucket-owner-full-control
CloudTrail:
Type: AWS::CloudTrail::Trail
DependsOn: CloudTrailBucketPolicy
Properties:
TrailName: organization-trail
S3BucketName: !Ref CloudTrailBucket
IncludeGlobalServiceEvents: true
IsLogging: true
IsMultiRegionTrail: true
EnableLogFileValidation: true
EventSelectors:
- ReadWriteType: All
IncludeManagementEvents: true
DataResources:
- Type: 'AWS::S3::Object'
Values:
- !Sub '${S3Bucket.Arn}/'
- Type: 'AWS::Lambda::Function'
Values:
- 'arn:aws:lambda:::function/'
undefinedCloudTrailBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 'cloudtrail-logs-${AWS::AccountId}'
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
LifecycleConfiguration:
Rules:
- Id: MoveToGlacier
Status: Enabled
Transitions:
- TransitionInDays: 90
StorageClass: GLACIER
ExpirationInDays: 2555
CloudTrailBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref CloudTrailBucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AWSCloudTrailAclCheck
Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Action: 's3:GetBucketAcl'
Resource: !GetAtt CloudTrailBucket.Arn
- Sid: AWSCloudTrailWrite
Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Action: 's3:PutObject'
Resource: !Sub '${CloudTrailBucket.Arn}/*'
Condition:
StringEquals:
's3:x-amz-acl': bucket-owner-full-control
CloudTrail:
Type: AWS::CloudTrail::Trail
DependsOn: CloudTrailBucketPolicy
Properties:
TrailName: organization-trail
S3BucketName: !Ref CloudTrailBucket
IncludeGlobalServiceEvents: true
IsLogging: true
IsMultiRegionTrail: true
EnableLogFileValidation: true
EventSelectors:
- ReadWriteType: All
IncludeManagementEvents: true
DataResources:
- Type: 'AWS::S3::Object'
Values:
- !Sub '${S3Bucket.Arn}/'
- Type: 'AWS::Lambda::Function'
Values:
- 'arn:aws:lambda:::function/'
undefinedServerless Architecture
无服务器架构
AWS Step Functions
AWS Step Functions
yaml
undefinedyaml
undefinedCloudFormation: Step Functions State Machine
CloudFormation: Step Functions状态机
StateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
StateMachineName: OrderProcessingWorkflow
RoleArn: !GetAtt StateMachineRole.Arn
DefinitionString: !Sub |
{
"Comment": "Order processing workflow",
"StartAt": "ValidateOrder",
"States": {
"ValidateOrder": {
"Type": "Task",
"Resource": "${ValidateOrderFunction.Arn}",
"Next": "CheckInventory",
"Catch": [{
"ErrorEquals": ["ValidationError"],
"ResultPath": "$.error",
"Next": "OrderFailed"
}]
},
"CheckInventory": {
"Type": "Task",
"Resource": "${CheckInventoryFunction.Arn}",
"Next": "IsInventoryAvailable",
"ResultPath": "$.inventory"
},
"IsInventoryAvailable": {
"Type": "Choice",
"Choices": [{
"Variable": "$.inventory.available",
"BooleanEquals": true,
"Next": "ProcessPayment"
}],
"Default": "OrderFailed"
},
"ProcessPayment": {
"Type": "Task",
"Resource": "${ProcessPaymentFunction.Arn}",
"Next": "UpdateInventory",
"Retry": [{
"ErrorEquals": ["PaymentServiceError"],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2.0
}],
"Catch": [{
"ErrorEquals": ["PaymentFailed"],
"ResultPath": "$.error",
"Next": "OrderFailed"
}]
},
"UpdateInventory": {
"Type": "Task",
"Resource": "${UpdateInventoryFunction.Arn}",
"Next": "SendConfirmation"
},
"SendConfirmation": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Parameters": {
"TopicArn": "${OrderConfirmationTopic}",
"Message.$": "$.confirmationMessage"
},
"Next": "OrderSucceeded"
},
"OrderSucceeded": {
"Type": "Succeed"
},
"OrderFailed": {
"Type": "Fail",
"Error": "OrderProcessingFailed",
"Cause": "Order could not be processed"
}
}
}
undefinedStateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
StateMachineName: OrderProcessingWorkflow
RoleArn: !GetAtt StateMachineRole.Arn
DefinitionString: !Sub |
{
"Comment": "订单处理工作流",
"StartAt": "ValidateOrder",
"States": {
"ValidateOrder": {
"Type": "Task",
"Resource": "${ValidateOrderFunction.Arn}",
"Next": "CheckInventory",
"Catch": [{
"ErrorEquals": ["ValidationError"],
"ResultPath": "$.error",
"Next": "OrderFailed"
}]
},
"CheckInventory": {
"Type": "Task",
"Resource": "${CheckInventoryFunction.Arn}",
"Next": "IsInventoryAvailable",
"ResultPath": "$.inventory"
},
"IsInventoryAvailable": {
"Type": "Choice",
"Choices": [{
"Variable": "$.inventory.available",
"BooleanEquals": true,
"Next": "ProcessPayment"
}],
"Default": "OrderFailed"
},
"ProcessPayment": {
"Type": "Task",
"Resource": "${ProcessPaymentFunction.Arn}",
"Next": "UpdateInventory",
"Retry": [{
"ErrorEquals": ["PaymentServiceError"],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2.0
}],
"Catch": [{
"ErrorEquals": ["PaymentFailed"],
"ResultPath": "$.error",
"Next": "OrderFailed"
}]
},
"UpdateInventory": {
"Type": "Task",
"Resource": "${UpdateInventoryFunction.Arn}",
"Next": "SendConfirmation"
},
"SendConfirmation": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Parameters": {
"TopicArn": "${OrderConfirmationTopic}",
"Message.$": "$.confirmationMessage"
},
"Next": "OrderSucceeded"
},
"OrderSucceeded": {
"Type": "Succeed"
},
"OrderFailed": {
"Type": "Fail",
"Error": "OrderProcessingFailed",
"Cause": "订单处理失败"
}
}
}
undefinedAmazon EventBridge
Amazon EventBridge
yaml
undefinedyaml
undefinedCloudFormation: EventBridge Rule
CloudFormation: EventBridge规则
EventBridgeRule:
Type: AWS::Events::Rule
Properties:
Name: S3ObjectCreatedRule
Description: Trigger processing when objects are created in S3
State: ENABLED
EventPattern:
source:
- aws.s3
detail-type:
- 'AWS API Call via CloudTrail'
detail:
eventSource:
- s3.amazonaws.com
eventName:
- PutObject
- CompleteMultipartUpload
requestParameters:
bucketName:
- !Ref S3Bucket
Targets:
- Arn: !GetAtt ProcessingFunction.Arn
Id: ProcessingLambda
- Arn: !Ref ProcessingQueue
Id: SQSQueue
- Arn: !GetAtt StateMachine.Arn
Id: StepFunctionsWorkflow
RoleArn: !GetAtt EventBridgeRole.Arn
undefinedEventBridgeRule:
Type: AWS::Events::Rule
Properties:
Name: S3ObjectCreatedRule
Description: S3中创建对象时触发处理流程
State: ENABLED
EventPattern:
source:
- aws.s3
detail-type:
- 'AWS API Call via CloudTrail'
detail:
eventSource:
- s3.amazonaws.com
eventName:
- PutObject
- CompleteMultipartUpload
requestParameters:
bucketName:
- !Ref S3Bucket
Targets:
- Arn: !GetAtt ProcessingFunction.Arn
Id: ProcessingLambda
- Arn: !Ref ProcessingQueue
Id: SQSQueue
- Arn: !GetAtt StateMachine.Arn
Id: StepFunctionsWorkflow
RoleArn: !GetAtt EventBridgeRole.Arn
undefinedCost Optimization
成本优化
EC2 Reserved Instances and Savings Plans
EC2预留实例与节省计划
bash
undefinedbash
undefinedDescribe Reserved Instance offerings
描述预留实例产品
aws ec2 describe-reserved-instances-offerings
--instance-type t3.medium
--offering-class standard
--product-description "Linux/UNIX"
--query 'ReservedInstancesOfferings[*].[InstanceType,Duration,FixedPrice,UsagePrice,OfferingClass]'
--output table
--instance-type t3.medium
--offering-class standard
--product-description "Linux/UNIX"
--query 'ReservedInstancesOfferings[*].[InstanceType,Duration,FixedPrice,UsagePrice,OfferingClass]'
--output table
aws ec2 describe-reserved-instances-offerings
--instance-type t3.medium
--offering-class standard
--product-description "Linux/UNIX"
--query 'ReservedInstancesOfferings[*].[InstanceType,Duration,FixedPrice,UsagePrice,OfferingClass]'
--output table
--instance-type t3.medium
--offering-class standard
--product-description "Linux/UNIX"
--query 'ReservedInstancesOfferings[*].[InstanceType,Duration,FixedPrice,UsagePrice,OfferingClass]'
--output table
Purchase Reserved Instance
购买预留实例
aws ec2 purchase-reserved-instances-offering
--reserved-instances-offering-id <offering-id>
--instance-count 2
--reserved-instances-offering-id <offering-id>
--instance-count 2
aws ec2 purchase-reserved-instances-offering
--reserved-instances-offering-id <offering-id>
--instance-count 2
--reserved-instances-offering-id <offering-id>
--instance-count 2
Describe Savings Plans
描述节省计划
aws savingsplans describe-savings-plans
--query 'savingsPlans[*].[savingsPlanId,savingsPlanType,commitment,ec2InstanceFamily]'
--output table
--query 'savingsPlans[*].[savingsPlanId,savingsPlanType,commitment,ec2InstanceFamily]'
--output table
undefinedaws savingsplans describe-savings-plans
--query 'savingsPlans[*].[savingsPlanId,savingsPlanType,commitment,ec2InstanceFamily]'
--output table
--query 'savingsPlans[*].[savingsPlanId,savingsPlanType,commitment,ec2InstanceFamily]'
--output table
undefinedAWS Cost Explorer and Budgets
AWS成本资源管理器与预算
yaml
undefinedyaml
undefinedCloudFormation: Budget with alerts
CloudFormation: 带告警的预算
MonthlyBudget:
Type: AWS::Budgets::Budget
Properties:
Budget:
BudgetName: Monthly-AWS-Budget
BudgetLimit:
Amount: 1000
Unit: USD
TimeUnit: MONTHLY
BudgetType: COST
CostFilters:
TagKeyValue:
- 'user:Environment$Production'
CostTypes:
IncludeTax: true
IncludeSubscription: true
UseBlended: false
NotificationsWithSubscribers:
- Notification:
NotificationType: ACTUAL
ComparisonOperator: GREATER_THAN
Threshold: 80
Subscribers:
- SubscriptionType: EMAIL
Address: admin@example.com
- Notification:
NotificationType: FORECASTED
ComparisonOperator: GREATER_THAN
Threshold: 100
Subscribers:
- SubscriptionType: EMAIL
Address: admin@example.com
- SubscriptionType: SNS
Address: !Ref AlertTopic
undefinedMonthlyBudget:
Type: AWS::Budgets::Budget
Properties:
Budget:
BudgetName: Monthly-AWS-Budget
BudgetLimit:
Amount: 1000
Unit: USD
TimeUnit: MONTHLY
BudgetType: COST
CostFilters:
TagKeyValue:
- 'user:Environment$Production'
CostTypes:
IncludeTax: true
IncludeSubscription: true
UseBlended: false
NotificationsWithSubscribers:
- Notification:
NotificationType: ACTUAL
ComparisonOperator: GREATER_THAN
Threshold: 80
Subscribers:
- SubscriptionType: EMAIL
Address: admin@example.com
- Notification:
NotificationType: FORECASTED
ComparisonOperator: GREATER_THAN
Threshold: 100
Subscribers:
- SubscriptionType: EMAIL
Address: admin@example.com
- SubscriptionType: SNS
Address: !Ref AlertTopic
undefinedS3 Intelligent-Tiering
S3智能分层
bash
undefinedbash
undefinedEnable S3 Intelligent-Tiering
启用S3智能分层
aws s3api put-bucket-intelligent-tiering-configuration
--bucket my-bucket
--id EntirePrefix
--intelligent-tiering-configuration '{ "Id": "EntirePrefix", "Status": "Enabled", "Tierings": [ { "Days": 90, "AccessTier": "ARCHIVE_ACCESS" }, { "Days": 180, "AccessTier": "DEEP_ARCHIVE_ACCESS" } ] }'
--bucket my-bucket
--id EntirePrefix
--intelligent-tiering-configuration '{ "Id": "EntirePrefix", "Status": "Enabled", "Tierings": [ { "Days": 90, "AccessTier": "ARCHIVE_ACCESS" }, { "Days": 180, "AccessTier": "DEEP_ARCHIVE_ACCESS" } ] }'
undefinedaws s3api put-bucket-intelligent-tiering-configuration
--bucket my-bucket
--id EntirePrefix
--intelligent-tiering-configuration '{ "Id": "EntirePrefix", "Status": "Enabled", "Tierings": [ { "Days": 90, "AccessTier": "ARCHIVE_ACCESS" }, { "Days": 180, "AccessTier": "DEEP_ARCHIVE_ACCESS" } ] }'
--bucket my-bucket
--id EntirePrefix
--intelligent-tiering-configuration '{ "Id": "EntirePrefix", "Status": "Enabled", "Tierings": [ { "Days": 90, "AccessTier": "ARCHIVE_ACCESS" }, { "Days": 180, "AccessTier": "DEEP_ARCHIVE_ACCESS" } ] }'
undefinedMonitoring and Operations
监控与运维
Amazon CloudWatch
Amazon CloudWatch
yaml
undefinedyaml
undefinedCloudFormation: CloudWatch Dashboard and Alarms
CloudFormation: CloudWatch仪表盘与告警
CloudWatchDashboard:
Type: AWS::CloudWatch::Dashboard
Properties:
DashboardName: Production-Dashboard
DashboardBody: !Sub |
{
"widgets": [
{
"type": "metric",
"properties": {
"metrics": [
["AWS/EC2", "CPUUtilization", {"stat": "Average"}],
["AWS/ApplicationELB", "TargetResponseTime"],
["AWS/RDS", "DatabaseConnections", {"stat": "Sum"}]
],
"period": 300,
"stat": "Average",
"region": "${AWS::Region}",
"title": "System Metrics"
}
}
]
}
HighCPUAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: High-CPU-Utilization
AlarmDescription: Alert when CPU exceeds 80%
MetricName: CPUUtilization
Namespace: AWS/EC2
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 80
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref SNSTopic
Dimensions:
- Name: InstanceId
Value: !Ref EC2Instance
DatabaseConnectionsAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: High-Database-Connections
MetricName: DatabaseConnections
Namespace: AWS/RDS
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 80
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref SNSTopic
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref RDSInstance
undefinedCloudWatchDashboard:
Type: AWS::CloudWatch::Dashboard
Properties:
DashboardName: Production-Dashboard
DashboardBody: !Sub |
{
"widgets": [
{
"type": "metric",
"properties": {
"metrics": [
["AWS/EC2", "CPUUtilization", {"stat": "Average"}],
["AWS/ApplicationELB", "TargetResponseTime"],
["AWS/RDS", "DatabaseConnections", {"stat": "Sum"}]
],
"period": 300,
"stat": "Average",
"region": "${AWS::Region}",
"title": "系统指标"
}
}
]
}
HighCPUAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: High-CPU-Utilization
AlarmDescription: CPU使用率超过80%时告警
MetricName: CPUUtilization
Namespace: AWS/EC2
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 80
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref SNSTopic
Dimensions:
- Name: InstanceId
Value: !Ref EC2Instance
DatabaseConnectionsAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: High-Database-Connections
MetricName: DatabaseConnections
Namespace: AWS/RDS
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 80
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref SNSTopic
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref RDSInstance
undefinedHigh Availability and Disaster Recovery
高可用性与灾难恢复
Multi-Region Architecture
多区域架构
yaml
undefinedyaml
undefinedCloudFormation: Route53 Health Check and Failover
CloudFormation: Route53健康检查与故障转移
HealthCheck:
Type: AWS::Route53::HealthCheck
Properties:
HealthCheckConfig:
Type: HTTPS
ResourcePath: /health
FullyQualifiedDomainName: !GetAtt ApplicationLoadBalancer.DNSName
Port: 443
RequestInterval: 30
FailureThreshold: 3
HealthCheckTags:
- Key: Name
Value: Primary-Region-HealthCheck
DNSRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostedZone
Name: api.example.com
Type: A
SetIdentifier: Primary
Failover: PRIMARY
AliasTarget:
HostedZoneId: !GetAtt ApplicationLoadBalancer.CanonicalHostedZoneID
DNSName: !GetAtt ApplicationLoadBalancer.DNSName
EvaluateTargetHealth: true
HealthCheckId: !Ref HealthCheck
DNSRecordSecondary:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostedZone
Name: api.example.com
Type: A
SetIdentifier: Secondary
Failover: SECONDARY
AliasTarget:
HostedZoneId: !GetAtt SecondaryLoadBalancer.CanonicalHostedZoneID
DNSName: !GetAtt SecondaryLoadBalancer.DNSName
EvaluateTargetHealth: true
undefinedHealthCheck:
Type: AWS::Route53::HealthCheck
Properties:
HealthCheckConfig:
Type: HTTPS
ResourcePath: /health
FullyQualifiedDomainName: !GetAtt ApplicationLoadBalancer.DNSName
Port: 443
RequestInterval: 30
FailureThreshold: 3
HealthCheckTags:
- Key: Name
Value: Primary-Region-HealthCheck
DNSRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostedZone
Name: api.example.com
Type: A
SetIdentifier: Primary
Failover: PRIMARY
AliasTarget:
HostedZoneId: !GetAtt ApplicationLoadBalancer.CanonicalHostedZoneID
DNSName: !GetAtt ApplicationLoadBalancer.DNSName
EvaluateTargetHealth: true
HealthCheckId: !Ref HealthCheck
DNSRecordSecondary:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostedZone
Name: api.example.com
Type: A
SetIdentifier: Secondary
Failover: SECONDARY
AliasTarget:
HostedZoneId: !GetAtt SecondaryLoadBalancer.CanonicalHostedZoneID
DNSName: !GetAtt SecondaryLoadBalancer.DNSName
EvaluateTargetHealth: true
undefinedBackup and Recovery
备份与恢复
yaml
undefinedyaml
undefinedCloudFormation: AWS Backup Plan
CloudFormation: AWS备份计划
BackupVault:
Type: AWS::Backup::BackupVault
Properties:
BackupVaultName: ProductionBackupVault
EncryptionKeyArn: !GetAtt KMSKey.Arn
BackupPlan:
Type: AWS::Backup::BackupPlan
Properties:
BackupPlan:
BackupPlanName: DailyBackupPlan
BackupPlanRule:
- RuleName: DailyBackup
TargetBackupVault: !Ref BackupVault
ScheduleExpression: 'cron(0 5 ? * * *)'
StartWindowMinutes: 60
CompletionWindowMinutes: 120
Lifecycle:
DeleteAfterDays: 35
MoveToColdStorageAfterDays: 30
- RuleName: WeeklyBackup
TargetBackupVault: !Ref BackupVault
ScheduleExpression: 'cron(0 5 ? * 1 *)'
Lifecycle:
DeleteAfterDays: 365
MoveToColdStorageAfterDays: 90
BackupSelection:
Type: AWS::Backup::BackupSelection
Properties:
BackupPlanId: !Ref BackupPlan
BackupSelection:
SelectionName: ProductionResources
IamRoleArn: !GetAtt BackupRole.Arn
Resources:
- !GetAtt RDSInstance.Arn
- !Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:volume/*'
ListOfTags:
- ConditionType: STRINGEQUALS
ConditionKey: Backup
ConditionValue: 'true'
undefinedBackupVault:
Type: AWS::Backup::BackupVault
Properties:
BackupVaultName: ProductionBackupVault
EncryptionKeyArn: !GetAtt KMSKey.Arn
BackupPlan:
Type: AWS::Backup::BackupPlan
Properties:
BackupPlan:
BackupPlanName: DailyBackupPlan
BackupPlanRule:
- RuleName: DailyBackup
TargetBackupVault: !Ref BackupVault
ScheduleExpression: 'cron(0 5 ? * * *)'
StartWindowMinutes: 60
CompletionWindowMinutes: 120
Lifecycle:
DeleteAfterDays: 35
MoveToColdStorageAfterDays: 30
- RuleName: WeeklyBackup
TargetBackupVault: !Ref BackupVault
ScheduleExpression: 'cron(0 5 ? * 1 *)'
Lifecycle:
DeleteAfterDays: 365
MoveToColdStorageAfterDays: 90
BackupSelection:
Type: AWS::Backup::BackupSelection
Properties:
BackupPlanId: !Ref BackupPlan
BackupSelection:
SelectionName: ProductionResources
IamRoleArn: !GetAtt BackupRole.Arn
Resources:
- !GetAtt RDSInstance.Arn
- !Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:volume/*'
ListOfTags:
- ConditionType: STRINGEQUALS
ConditionKey: Backup
ConditionValue: 'true'
undefinedBest Practices Summary
最佳实践总结
- Security: Always encrypt data at rest and in transit, use least privilege IAM policies, enable MFA
- High Availability: Deploy across multiple Availability Zones, use Auto Scaling
- Cost Optimization: Right-size resources, use Reserved Instances/Savings Plans, implement lifecycle policies
- Performance: Use caching (CloudFront, ElastiCache), optimize database queries, leverage CDN
- Reliability: Implement automated backups, test disaster recovery procedures, monitor everything
- Operational Excellence: Automate deployment with Infrastructure as Code, implement CI/CD pipelines
- Sustainability: Use managed services, optimize resource utilization, shutdown non-production resources
This skill provides comprehensive coverage of AWS cloud architecture following the Well-Architected Framework pillars. All examples are production-ready and follow AWS best practices.
- 安全:始终加密静态和传输中的数据,使用最小权限IAM策略,启用多因素认证
- 高可用性:跨多个可用区部署,使用自动扩缩容
- 成本优化:合理调整资源规格,使用预留实例/节省计划,实施生命周期策略
- 性能:使用缓存(CloudFront、ElastiCache),优化数据库查询,利用CDN
- 可靠性:实施自动备份,测试灾难恢复流程,全面监控
- 运营卓越:使用基础设施即代码自动化部署,实施CI/CD流水线
- 可持续性:使用托管服务,优化资源利用率,关闭非生产资源
本指南全面覆盖了遵循架构完善框架支柱的AWS云架构内容。所有示例均为生产就绪型,且符合AWS最佳实践。