Loading...
Loading...
Compare original and translation side by side
cloud-architecturecloud-architecturereferencesreferencesSKILL.mdSKILL.md| Category | Artifact | Format | Example |
|---|---|---|---|
| Correctness | Cloud topology decision record | Markdown doc per | |
| Security | Cloud account hardening checklist | Markdown doc covering root-account, IAM, network, and logging baseline | |
| 分类 | 工件 | 格式 | 示例 |
|---|---|---|---|
| 正确性 | 云拓扑决策记录 | 遵循 | |
| 安全性 | 云账户加固检查清单 | 涵盖根账户、IAM、网络和日志基线的Markdown文档 | |
references/references/world-class-engineeringsystem-architecture-designcicd-pipelinescicd-devsecopsobservability-monitoringdeployment-release-engineeringreliability-engineeringworld-class-engineeringsystem-architecture-designcicd-pipelinescicd-devsecopsobservability-monitoringdeployment-release-engineeringreliability-engineeringdocker-compose.ymldocker-compose.yml| Dimension | AWS | GCP | Azure |
|---|---|---|---|
| Closest region | | | |
| Data-residency fit | Strong (af-south-1 + KMS) | Weak (no ZA region for many services) | Strong (ZA North + Customer Lockbox) |
| Support in EAT | 24/7 Business; EMEA TAM overlap | 24/7 Standard | 24/7 ProDirect; ZA partners |
| Managed services breadth | Widest | Data/ML led | Microsoft-stack integration |
af-south-1southafricanorthaws configure set region af-south-1 --profile ug-prod
aws ec2 describe-availability-zones --region af-south-1 --query "AvailabilityZones[].ZoneName"| 维度 | AWS | GCP | Azure |
|---|---|---|---|
| 最近区域 | | | |
| 数据驻留适配性 | 强(af-south-1 + KMS) | 弱(多数服务无南非区域) | 强(南非北部区域 + Customer Lockbox) |
| 东非时间支持 | 7×24小时商务支持;EMEA技术客户经理重叠 | 7×24小时标准支持 | 7×24小时ProDirect支持;南非合作伙伴 |
| 托管服务广度 | 最广 | 以数据/ML为主 | 与Microsoft栈深度集成 |
af-south-1southafricanorthaws configure set region af-south-1 --profile ug-prod
aws ec2 describe-availability-zones --region af-south-1 --query "AvailabilityZones[].ZoneName"kubernetes-platformkubernetes-platformbuildernode:22.11.0-slim@sha256:...alpineUSER nonrootWORKDIREXPOSEHEALTHCHECK.dockerignore.gitnode_modulesCOPYbuildernode:22.11.0-slim@sha256:...alpineUSER nonrootWORKDIREXPOSEHEALTHCHECK.dockerignore.gitnode_modulesCOPYundefinedundefinedundefinedundefineddocker-compose.ymlhealthcheckdepends_on.condition: service_healthyname: saas-local
services:
web:
build: .
env_file: .env
ports: ["3000:3000"]
depends_on:
db: { condition: service_healthy }
redis: { condition: service_healthy }
healthcheck:
test: ["CMD", "node", "dist/healthcheck.js"]
interval: 30s
timeout: 5s
retries: 3
db:
image: postgres:16.4-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
POSTGRES_DB: app
volumes: ["db-data:/var/lib/postgresql/data"]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d app"]
interval: 10s
timeout: 3s
retries: 5
secrets: [db_password]
redis:
image: redis:7.4-alpine
command: ["redis-server", "--appendonly", "yes"]
volumes: ["redis-data:/data"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
volumes:
db-data: {}
redis-data: {}
secrets:
db_password: { file: ./.secrets/db_password }.env.example.envreferences/docker-compose-patterns.mddocker-compose.ymlhealthcheckdepends_on.condition: service_healthyname: saas-local
services:
web:
build: .
env_file: .env
ports: ["3000:3000"]
depends_on:
db: { condition: service_healthy }
redis: { condition: service_healthy }
healthcheck:
test: ["CMD", "node", "dist/healthcheck.js"]
interval: 30s
timeout: 5s
retries: 3
db:
image: postgres:16.4-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
POSTGRES_DB: app
volumes: ["db-data:/var/lib/postgresql/data"]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d app"]
interval: 10s
timeout: 3s
retries: 5
secrets: [db_password]
redis:
image: redis:7.4-alpine
command: ["redis-server", "--appendonly", "yes"]
volumes: ["redis-data:/data"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
volumes:
db-data: {}
redis-data: {}
secrets:
db_password: { file: ./.secrets/db_password }.env.example.envreferences/docker-compose-patterns.mdt3t4gm6im7ic6ic7ir6ir7ii4iLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: app-prod-lt
LaunchTemplateData:
ImageId: ami-0123456789abcdef0
InstanceType: m6i.large
IamInstanceProfile: { Name: app-prod-instance-profile }
SecurityGroupIds: [sg-app]
MetadataOptions: { HttpTokens: required, HttpEndpoint: enabled }
AppASG:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MinSize: 2
MaxSize: 10
DesiredCapacity: 3
HealthCheckType: ELB
HealthCheckGracePeriod: 120
VPCZoneIdentifier: [subnet-priv-a, subnet-priv-b, subnet-priv-c]
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
TargetGroupARNs: [!Ref AppTargetGroup]t3t4gm6im7ic6ic7ir6ir7ii4iLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: app-prod-lt
LaunchTemplateData:
ImageId: ami-0123456789abcdef0
InstanceType: m6i.large
IamInstanceProfile: { Name: app-prod-instance-profile }
SecurityGroupIds: [sg-app]
MetadataOptions: { HttpTokens: required, HttpEndpoint: enabled }
AppASG:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MinSize: 2
MaxSize: 10
DesiredCapacity: 3
HealthCheckType: ELB
HealthCheckGracePeriod: 120
VPCZoneIdentifier: [subnet-priv-a, subnet-priv-b, subnet-priv-c]
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
TargetGroupARNs: [!Ref AppTargetGroup]aws s3 presign s3://app-prod-uploads/customer/42/invoice.pdf \
--expires-in 900 --region af-south-1
aws configure set default.s3.multipart_threshold 100MB
aws configure set default.s3.multipart_chunksize 16MB{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::app-prod-uploads", "arn:aws:s3:::app-prod-uploads/*"],
"Condition": { "Bool": { "aws:SecureTransport": "false" } }
}
]
}aws s3 presign s3://app-prod-uploads/customer/42/invoice.pdf \
--expires-in 900 --region af-south-1
aws configure set default.s3.multipart_threshold 100MB
aws configure set default.s3.multipart_chunksize 16MB{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::app-prod-uploads", "arn:aws:s3:::app-prod-uploads/*"],
"Condition": { "Bool": { "aws:SecureTransport": "false" } }
}
]
}aws rds create-db-parameter-group --db-parameter-group-name app-pg16-prod \
--db-parameter-group-family postgres16 --description "Prod PG16 params"
aws rds create-db-instance --db-instance-identifier app-prod \
--engine postgres --engine-version 16.4 --db-instance-class db.m6i.large \
--allocated-storage 200 --storage-type gp3 --storage-encrypted \
--multi-az --backup-retention-period 14 --db-parameter-group-name app-pg16-prod \
--monitoring-interval 60 --enable-performance-insightsaws rds create-db-parameter-group --db-parameter-group-name app-pg16-prod \
--db-parameter-group-family postgres16 --description "Prod PG16 params"
aws rds create-db-instance --db-instance-identifier app-prod \
--engine postgres --engine-version 16.4 --db-instance-class db.m6i.large \
--allocated-storage 200 --storage-type gp3 --storage-encrypted \
--multi-az --backup-retention-period 14 --db-parameter-group-name app-pg16-prod \
--monitoring-interval 60 --enable-performance-insightsaws lambda put-provisioned-concurrency-config \
--function-name order-api --qualifier live \
--provisioned-concurrent-executions 5aws lambda put-provisioned-concurrency-config \
--function-name order-api --qualifier live \
--provisioned-concurrent-executions 5*:*{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AppReadUploads",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::app-prod-uploads/*"
},
{
"Sid": "AppReadSecrets",
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:af-south-1:111122223333:secret:app/prod/*"
}
]
}*:*{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AppReadUploads",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::app-prod-uploads/*"
},
{
"Sid": "AppReadSecrets",
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:af-south-1:111122223333:secret:app/prod/*"
}
]
}| Layer | CIDR example | Routing |
|---|---|---|
| Public subnets | 10.20.0.0/20 per AZ | IGW default route |
| Private app subnets | 10.20.32.0/20 per AZ | NAT gateway in same AZ |
| Private data subnets | 10.20.64.0/20 per AZ | No outbound route |
aws ec2 create-vpc --cidr-block 10.20.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=ug-prod-vpc}]'
aws ec2 create-nat-gateway --subnet-id subnet-pub-a --allocation-id eipalloc-aaa| 层级 | CIDR示例 | 路由配置 |
|---|---|---|
| 公共子网 | 每个可用区10.20.0.0/20 | 默认路由指向IGW |
| 私有应用子网 | 每个可用区10.20.32.0/20 | 指向同可用区的NAT网关 |
| 私有数据子网 | 每个可用区10.20.64.0/20 | 无出站路由 |
aws ec2 create-vpc --cidr-block 10.20.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=ug-prod-vpc}]'
aws ec2 create-nat-gateway --subnet-id subnet-pub-a --allocation-id eipalloc-aaa| Feature | ALB | NLB |
|---|---|---|
| Layer | 7 (HTTP/HTTPS/gRPC) | 4 (TCP/UDP/TLS) |
| Routing | Host, path, header, query | Port-based |
| TLS termination | At ALB | Passthrough or at NLB |
| Sticky sessions | Cookie-based | Source-IP flow hash |
| Use case | Web APIs, microservices | High-throughput TCP, static IPs, PrivateLink |
/healthzaws elbv2 create-target-group --name app-tg-blue --protocol HTTP --port 3000 \
--vpc-id vpc-0abc --health-check-path /healthz --health-check-interval-seconds 15 \
--healthy-threshold-count 2 --unhealthy-threshold-count 3 --matcher HttpCode=200
aws elbv2 create-listener --load-balancer-arn $ALB_ARN --protocol HTTPS --port 443 \
--certificates CertificateArn=$ACM_ARN \
--ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 \
--default-actions Type=forward,TargetGroupArn=$TG_BLUE| 特性 | ALB | NLB |
|---|---|---|
| 层级 | 7层(HTTP/HTTPS/gRPC) | 4层(TCP/UDP/TLS) |
| 路由方式 | 基于主机、路径、头信息、查询参数 | 基于端口 |
| TLS终止 | 在ALB层 | 透传或在NLB层 |
| 会话保持 | 基于Cookie | 基于源IP流哈希 |
| 适用场景 | Web API、微服务 | 高吞吐量TCP、静态IP、PrivateLink |
/healthzaws elbv2 create-target-group --name app-tg-blue --protocol HTTP --port 3000 \
--vpc-id vpc-0abc --health-check-path /healthz --health-check-interval-seconds 15 \
--healthy-threshold-count 2 --unhealthy-threshold-count 3 --matcher HttpCode=200
aws elbv2 create-listener --load-balancer-arn $ALB_ARN --protocol HTTPS --port 443 \
--certificates CertificateArn=$ACM_ARN \
--ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 \
--default-actions Type=forward,TargetGroupArn=$TG_BLUEaws cloudfront create-distribution --distribution-config file://cf-dist.json
aws wafv2 create-web-acl --name app-prod-waf --scope CLOUDFRONT --default-action Allow={} \
--visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=app-prod-waf \
--rules file://waf-managed-rules.jsoninvalidate /*/static/v=<build-sha>/aws cloudfront create-distribution --distribution-config file://cf-dist.json
aws wafv2 create-web-acl --name app-prod-waf --scope CLOUDFRONT --default-action Allow={} \
--visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=app-prod-waf \
--rules file://waf-managed-rules.jsoninvalidate /*/static/v=<build-sha>/cert-managerClusterIssueraws acm request-certificate --domain-name app.example.co.ug \
--subject-alternative-names "*.app.example.co.ug" \
--validation-method DNS --key-algorithm RSA_2048
sudo certbot --nginx -d app.example.co.ug --deploy-hook "systemctl reload nginx"
kubectl apply -f cert-manager/letsencrypt-prod-issuer.yamlmax-age=31536000; includeSubDomains; preloadcert-managerClusterIssueraws acm request-certificate --domain-name app.example.co.ug \
--subject-alternative-names "*.app.example.co.ug" \
--validation-method DNS --key-algorithm RSA_2048
sudo certbot --nginx -d app.example.co.ug --deploy-hook "systemctl reload nginx"
kubectl apply -f cert-manager/letsencrypt-prod-issuer.yamlmax-age=31536000; includeSubDomains; preloadaws application-autoscaling put-scaling-policy --service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount --resource-id service/app-cluster/app-svc \
--policy-name tt-reqcount --policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 1000,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ALBRequestCountPerTarget",
"ResourceLabel": "app/alb-arn/tg-arn"
},
"ScaleOutCooldown": 60, "ScaleInCooldown": 300
}'aws application-autoscaling put-scaling-policy --service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount --resource-id service/app-cluster/app-svc \
--policy-name tt-reqcount --policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 1000,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ALBRequestCountPerTarget",
"ResourceLabel": "app/alb-arn/tg-arn"
},
"ScaleOutCooldown": 60, "ScaleInCooldown": 300
}'app-tg-greenhealthyaws elbv2 describe-target-healthaws elbv2 modify-listener --listener-arn $LISTENER_ARN \
--default-actions Type=forward,TargetGroupArn=$TG_GREENaws autoscaling start-instance-refresh --auto-scaling-group-name app-prod-asg \
--strategy Rolling --preferences '{
"MinHealthyPercentage": 90, "InstanceWarmup": 180,
"CheckpointPercentages": [25, 50, 100], "CheckpointDelay": 600
}'app-tg-blueaws autoscaling cancel-instance-refreshapp-tg-greenaws elbv2 describe-target-healthhealthyaws elbv2 modify-listener --listener-arn $LISTENER_ARN \
--default-actions Type=forward,TargetGroupArn=$TG_GREENaws autoscaling start-instance-refresh --auto-scaling-group-name app-prod-asg \
--strategy Rolling --preferences '{
"MinHealthyPercentage": 90, "InstanceWarmup": 180,
"CheckpointPercentages": [25, 50, 100], "CheckpointDelay": 600
}'app-tg-blueaws autoscaling cancel-instance-refresheu-west-1aws rds copy-db-snapshot \
--source-db-snapshot-identifier arn:aws:rds:af-south-1:111122223333:snapshot:app-prod-2026-04-15 \
--target-db-snapshot-identifier app-prod-2026-04-15-dr \
--kms-key-id alias/rds-dr --source-region af-south-1 --region eu-west-1
aws s3api put-bucket-versioning --bucket app-prod-uploads --versioning-configuration Status=Enabledeu-west-1aws rds copy-db-snapshot \
--source-db-snapshot-identifier arn:aws:rds:af-south-1:111122223333:snapshot:app-prod-2026-04-15 \
--target-db-snapshot-identifier app-prod-2026-04-15-dr \
--kms-key-id alias/rds-dr --source-region af-south-1 --region eu-west-1
aws s3api put-bucket-versioning --bucket app-prod-uploads --versioning-configuration Status=EnabledEnvironmentTeamCostCenterProjectaws ce list-cost-allocation-tags --status Active --region us-east-1
aws budgets create-budget --account-id 111122223333 --budget '{
"BudgetName": "ug-prod-monthly",
"BudgetLimit": { "Amount": "5000", "Unit": "USD" },
"TimeUnit": "MONTHLY", "BudgetType": "COST",
"CostFilters": { "TagKeyValue": ["user:Environment$prod"] }
}'EnvironmentTeamCostCenterProjectaws ce list-cost-allocation-tags --status Active --region us-east-1
aws budgets create-budget --account-id 111122223333 --budget '{
"BudgetName": "ug-prod-monthly",
"BudgetLimit": { "Amount": "5000", "Unit": "USD" },
"TimeUnit": "MONTHLY", "BudgetType": "COST",
"CostFilters": { "TagKeyValue": ["user:Environment$prod"] }
}'af-south-1eu-west-1us-east-1af-south-1af-south-1_context/compliance.mdaf-south-1eu-west-1aws route53 create-health-check --caller-reference "ug-app-$(date +%s)" --health-check-config file://hc.json
aws dynamodb update-table --table-name orders --replica-updates '[{"Create": {"RegionName": "eu-west-1"}}]'af-south-1eu-west-1us-east-1af-south-1af-south-1_context/compliance.mdaf-south-1eu-west-1aws route53 create-health-check --caller-reference "ug-app-$(date +%s)" --health-check-config file://hc.json
aws dynamodb update-table --table-name orders --replica-updates '[{"Create": {"RegionName": "eu-west-1"}}]'aws cloudtrail create-trail --name org-trail --s3-bucket-name org-cloudtrail-logs \
--is-multi-region-trail --is-organization-trail --enable-log-file-validation \
--kms-key-id alias/cloudtrail
aws cloudtrail start-logging --name org-trail
aws s3api put-bucket-versioning --bucket org-cloudtrail-logs --versioning-configuration Status=Enabled
aws configservice start-configuration-recorder --configuration-recorder-name default
aws guardduty create-detector --enable --finding-publishing-frequency FIFTEEN_MINUTES
aws securityhub enable-security-hub --enable-default-standards
aws accessanalyzer create-analyzer --analyzer-name org-analyzer --type ORGANIZATIONaws cloudtrail create-trail --name org-trail --s3-bucket-name org-cloudtrail-logs \
--is-multi-region-trail --is-organization-trail --enable-log-file-validation \
--kms-key-id alias/cloudtrail
aws cloudtrail start-logging --name org-trail
aws s3api put-bucket-versioning --bucket org-cloudtrail-logs --versioning-configuration Status=Enabled
aws configservice start-configuration-recorder --configuration-recorder-name default
aws guardduty create-detector --enable --finding-publishing-frequency FIFTEEN_MINUTES
aws securityhub enable-security-hub --enable-default-standards
aws accessanalyzer create-analyzer --analyzer-name org-analyzer --type ORGANIZATIONawsdockeraws configure ssoawsdockeraws configure sso