Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Migrasi template AWS CloudFormation CodeDeploy blue/green deployment template to an Amazon ECS blue/green AWS CloudFormation
Migrasikan AWS CloudFormation template yang menggunakan strategi CodeDeploy blue/green deployments for Amazon ECS services to one that uses the native Amazon ECS blue/green penerapan. Migrasi mengikuti pendekatan “Gunakan kembali sumber daya Elastic Load Balancing yang sama yang digunakan CodeDeploy untuk”. Untuk informasi lebih lanjut, lihat Migrasikan penerapan CodeDeploy blue/green deployments to Amazon ECS blue/green dokumentasi.
Template sumber
Template ini menggunakan AWS::CodeDeployBlueGreen
transform dan AWS::CodeDeploy::BlueGreen
hook untuk mengimplementasikan blue/green penerapan untuk layanan Amazon ECS.
Ini adalah AWS CloudFormation template lengkap menggunakan penyebaran CodeDeploy biru/hijau. Untuk informasi selengkapnya, lihat contoh templat penerapan biru/hijau di Panduan Pengguna: AWS CloudFormation
{ "AWSTemplateFormatVersion": "2010-09-09", "Parameters": { "Vpc": { "Type": "AWS::EC2::VPC::Id" }, "Subnet1": { "Type": "AWS::EC2::Subnet::Id" }, "Subnet2": { "Type": "AWS::EC2::Subnet::Id" } }, "Transform": [ "AWS::CodeDeployBlueGreen" ], "Hooks": { "CodeDeployBlueGreenHook": { "Type": "AWS::CodeDeploy::BlueGreen", "Properties": { "TrafficRoutingConfig": { "Type": "TimeBasedCanary", "TimeBasedCanary": { "StepPercentage": 15, "BakeTimeMins": 5 } }, "Applications": [ { "Target": { "Type": "AWS::ECS::Service", "LogicalID": "ECSDemoService" }, "ECSAttributes": { "TaskDefinitions": [ "BlueTaskDefinition", "GreenTaskDefinition" ], "TaskSets": [ "BlueTaskSet", "GreenTaskSet" ], "TrafficRouting": { "ProdTrafficRoute": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "LogicalID": "ALBListenerProdTraffic" }, "TargetGroups": [ "ALBTargetGroupBlue", "ALBTargetGroupGreen" ] } } } ] } } }, "Resources": { "ExampleSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Security group for ec2 access", "VpcId": {"Ref": "Vpc"}, "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": 8080, "ToPort": 8080, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "CidrIp": "0.0.0.0/0" } ] } }, "ALBTargetGroupBlue": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "HealthCheckIntervalSeconds": 5, "HealthCheckPath": "/", "HealthCheckPort": "80", "HealthCheckProtocol": "HTTP", "HealthCheckTimeoutSeconds": 2, "HealthyThresholdCount": 2, "Matcher": { "HttpCode": "200" }, "Port": 80, "Protocol": "HTTP", "Tags": [ { "Key": "Group", "Value": "Example" } ], "TargetType": "ip", "UnhealthyThresholdCount": 4, "VpcId": {"Ref": "Vpc"} } }, "ALBTargetGroupGreen": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "HealthCheckIntervalSeconds": 5, "HealthCheckPath": "/", "HealthCheckPort": "80", "HealthCheckProtocol": "HTTP", "HealthCheckTimeoutSeconds": 2, "HealthyThresholdCount": 2, "Matcher": { "HttpCode": "200" }, "Port": 80, "Protocol": "HTTP", "Tags": [ { "Key": "Group", "Value": "Example" } ], "TargetType": "ip", "UnhealthyThresholdCount": 4, "VpcId": {"Ref": "Vpc"} } }, "ExampleALB": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "Scheme": "internet-facing", "SecurityGroups": [ {"Ref": "ExampleSecurityGroup"} ], "Subnets": [ {"Ref": "Subnet1"}, {"Ref": "Subnet2"} ], "Tags": [ { "Key": "Group", "Value": "Example" } ], "Type": "application", "IpAddressType": "ipv4" } }, "ALBListenerProdTraffic": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "Type": "forward", "ForwardConfig": { "TargetGroups": [ { "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"}, "Weight": 1 } ] } } ], "LoadBalancerArn": {"Ref": "ExampleALB"}, "Port": 80, "Protocol": "HTTP" } }, "ALBListenerProdRule": { "Type": "AWS::ElasticLoadBalancingV2::ListenerRule", "Properties": { "Actions": [ { "Type": "forward", "ForwardConfig": { "TargetGroups": [ { "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"}, "Weight": 1 } ] } } ], "Conditions": [ { "Field": "http-header", "HttpHeaderConfig": { "HttpHeaderName": "User-Agent", "Values": [ "Mozilla" ] } } ], "ListenerArn": {"Ref": "ALBListenerProdTraffic"}, "Priority": 1 } }, "ECSTaskExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ecs-tasks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" ] } }, "BlueTaskDefinition": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ExecutionRoleArn": {"Fn::GetAtt": ["ECSTaskExecutionRole", "Arn"]}, "ContainerDefinitions": [ { "Name": "DemoApp", "Image": "nginxdemos/hello:latest", "Essential": true, "PortMappings": [ { "HostPort": 80, "Protocol": "tcp", "ContainerPort": 80 } ] } ], "RequiresCompatibilities": [ "FARGATE" ], "NetworkMode": "awsvpc", "Cpu": "256", "Memory": "512", "Family": "ecs-demo" } }, "ECSDemoCluster": { "Type": "AWS::ECS::Cluster", "Properties": {} }, "ECSDemoService": { "Type": "AWS::ECS::Service", "Properties": { "Cluster": {"Ref": "ECSDemoCluster"}, "DesiredCount": 1, "DeploymentController": { "Type": "EXTERNAL" } } }, "BlueTaskSet": { "Type": "AWS::ECS::TaskSet", "Properties": { "Cluster": {"Ref": "ECSDemoCluster"}, "LaunchType": "FARGATE", "NetworkConfiguration": { "AwsVpcConfiguration": { "AssignPublicIp": "ENABLED", "SecurityGroups": [ {"Ref": "ExampleSecurityGroup"} ], "Subnets": [ {"Ref": "Subnet1"}, {"Ref": "Subnet2"} ] } }, "PlatformVersion": "1.4.0", "Scale": { "Unit": "PERCENT", "Value": 100 }, "Service": {"Ref": "ECSDemoService"}, "TaskDefinition": {"Ref": "BlueTaskDefinition"}, "LoadBalancers": [ { "ContainerName": "DemoApp", "ContainerPort": 80, "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"} } ] } }, "PrimaryTaskSet": { "Type": "AWS::ECS::PrimaryTaskSet", "Properties": { "Cluster": {"Ref": "ECSDemoCluster"}, "Service": {"Ref": "ECSDemoService"}, "TaskSetId": {"Fn::GetAtt": ["BlueTaskSet", "Id"]} } } } }
Langkah migrasi
Hapus CodeDeploy sumber daya -spesifik
Anda tidak lagi membutuhkan properti berikut:
-
AWS::CodeDeployBlueGreen
Transformasi -
CodeDeployBlueGreenHook
Kaitnya -
GreenTaskSet
Sumber dayaGreenTaskDefinition
dan sumber daya (ini akan dikelola oleh Amazon ECS) -
Sumber
PrimaryTaskSet
daya (Amazon ECS akan mengelola set tugas secara internal)
Konfigurasikan ulang pendengar penyeimbang beban
Ubah ALBListenerProdTraffic
sumber daya untuk menggunakan tindakan maju dengan dua kelompok target:
{ "DefaultActions": [ { "Type": "forward", "ForwardConfig": { "TargetGroups": [ { "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"}, "Weight": 1 }, { "TargetGroupArn": {"Ref": "ALBTargetGroupGreen"}, "Weight": 0 } ] } } ] }
Perbarui properti penerapan
Perbarui dan tambahkan yang berikut ini:
-
Ubah
DeploymentController
properti dariEXTERNAL
keECS
. -
Tambahkan
Strategy
properti dan atur ke BLUE_GREEN. -
Tambahkan
BakeTimeInMinutes
properti.{ "DeploymentConfiguration": { "MaximumPercent": 200, "MinimumHealthyPercent": 100, "DeploymentCircuitBreaker": { "Enable": true, "Rollback": true }, "BakeTimeInMinutes": 5, "Strategy": "BLUE_GREEN" } }
-
Tambahkan konfigurasi penyeimbang beban ke layanan:
{ "LoadBalancers": [ { "ContainerName": "DemoApp", "ContainerPort": 80, "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"}, "AdvancedConfiguration": { "AlternateTargetGroupArn": {"Ref": "ALBTargetGroupGreen"}, "ProductionListenerRule": {"Ref": "ALBListenerProdRule"}, "RoleArn": {"Fn::GetAtt": ["ECSInfrastructureRoleForLoadBalancers", "Arn"]} } } ] }
-
Tambahkan referensi definisi tugas ke layanan:
{ "TaskDefinition": {"Ref": "BlueTaskDefinition"} }
Buat ECSInfrastructure RolePolicyForLoadBalancers peran Amazon
Tambahkan peran IAM baru yang memungkinkan Amazon ECS mengelola sumber daya penyeimbang beban:
Ganti user-input
dengan nilai Anda.
{ "ECSInfrastructureRoleForLoadBalancers": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccessToECSForInfrastructureManagement", "Effect": "Allow", "Principal": { "Service": "ecs.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "ManagedPolicyArns": [ "
arn:aws:iam::aws:policy/AmazonECSInfrastructureRolePolicyForLoadBalancers
" ] } } }
Rekomendasi pengujian
-
Menerapkan template yang dimigrasi ke lingkungan non-produksi.
-
Verifikasi bahwa layanan diterapkan dengan benar dengan konfigurasi awal.
-
Uji penerapan dengan memperbarui definisi tugas dan mengamati proses penerapan biru/hijau.
-
Verifikasi bahwa lalu lintas bergeser dengan benar antara penerapan biru dan hijau.
-
Uji fungsionalitas rollback dengan memaksa kegagalan penerapan.
Template setelah migrasi
Ini adalah AWS CloudFormation template lengkap menggunakan blue/green penyebaran Amazon ECS:
{ "AWSTemplateFormatVersion": "2010-09-09", "Parameters": { "Vpc": { "Type": "AWS::EC2::VPC::Id" }, "Subnet1": { "Type": "AWS::EC2::Subnet::Id" }, "Subnet2": { "Type": "AWS::EC2::Subnet::Id" } }, "Resources": { "ExampleSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Security group for ec2 access", "VpcId": {"Ref": "Vpc"}, "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": 8080, "ToPort": 8080, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "CidrIp": "0.0.0.0/0" } ] } }, "ALBTargetGroupBlue": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "HealthCheckIntervalSeconds": 5, "HealthCheckPath": "/", "HealthCheckPort": "80", "HealthCheckProtocol": "HTTP", "HealthCheckTimeoutSeconds": 2, "HealthyThresholdCount": 2, "Matcher": { "HttpCode": "200" }, "Port": 80, "Protocol": "HTTP", "Tags": [ { "Key": "Group", "Value": "Example" } ], "TargetType": "ip", "UnhealthyThresholdCount": 4, "VpcId": {"Ref": "Vpc"} } }, "ALBTargetGroupGreen": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "HealthCheckIntervalSeconds": 5, "HealthCheckPath": "/", "HealthCheckPort": "80", "HealthCheckProtocol": "HTTP", "HealthCheckTimeoutSeconds": 2, "HealthyThresholdCount": 2, "Matcher": { "HttpCode": "200" }, "Port": 80, "Protocol": "HTTP", "Tags": [ { "Key": "Group", "Value": "Example" } ], "TargetType": "ip", "UnhealthyThresholdCount": 4, "VpcId": {"Ref": "Vpc"} } }, "ExampleALB": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "Scheme": "internet-facing", "SecurityGroups": [ {"Ref": "ExampleSecurityGroup"} ], "Subnets": [ {"Ref": "Subnet1"}, {"Ref": "Subnet2"} ], "Tags": [ { "Key": "Group", "Value": "Example" } ], "Type": "application", "IpAddressType": "ipv4" } }, "ALBListenerProdTraffic": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "Type": "forward", "ForwardConfig": { "TargetGroups": [ { "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"}, "Weight": 1 }, { "TargetGroupArn": {"Ref": "ALBTargetGroupGreen"}, "Weight": 0 } ] } } ], "LoadBalancerArn": {"Ref": "ExampleALB"}, "Port": 80, "Protocol": "HTTP" } }, "ALBListenerProdRule": { "Type": "AWS::ElasticLoadBalancingV2::ListenerRule", "Properties": { "Actions": [ { "Type": "forward", "ForwardConfig": { "TargetGroups": [ { "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"}, "Weight": 1 }, { "TargetGroupArn": {"Ref": "ALBTargetGroupGreen"}, "Weight": 0 } ] } } ], "Conditions": [ { "Field": "http-header", "HttpHeaderConfig": { "HttpHeaderName": "User-Agent", "Values": [ "Mozilla" ] } } ], "ListenerArn": {"Ref": "ALBListenerProdTraffic"}, "Priority": 1 } }, "ECSTaskExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ecs-tasks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" ] } }, "ECSInfrastructureRoleForLoadBalancers": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccessToECSForInfrastructureManagement", "Effect": "Allow", "Principal": { "Service": "ecs.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/AmazonECSInfrastructureRolePolicyForLoadBalancers" ] } }, "BlueTaskDefinition": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ExecutionRoleArn": {"Fn::GetAtt": ["ECSTaskExecutionRole", "Arn"]}, "ContainerDefinitions": [ { "Name": "DemoApp", "Image": "nginxdemos/hello:latest", "Essential": true, "PortMappings": [ { "HostPort": 80, "Protocol": "tcp", "ContainerPort": 80 } ] } ], "RequiresCompatibilities": [ "FARGATE" ], "NetworkMode": "awsvpc", "Cpu": "256", "Memory": "512", "Family": "ecs-demo" } }, "ECSDemoCluster": { "Type": "AWS::ECS::Cluster", "Properties": {} }, "ECSDemoService": { "Type": "AWS::ECS::Service", "Properties": { "Cluster": {"Ref": "ECSDemoCluster"}, "DesiredCount": 1, "DeploymentController": { "Type": "ECS" }, "DeploymentConfiguration": { "MaximumPercent": 200, "MinimumHealthyPercent": 100, "DeploymentCircuitBreaker": { "Enable": true, "Rollback": true }, "BakeTimeInMinutes": 5, "Strategy": "BLUE_GREEN" }, "NetworkConfiguration": { "AwsvpcConfiguration": { "AssignPublicIp": "ENABLED", "SecurityGroups": [ {"Ref": "ExampleSecurityGroup"} ], "Subnets": [ {"Ref": "Subnet1"}, {"Ref": "Subnet2"} ] } }, "LaunchType": "FARGATE", "PlatformVersion": "1.4.0", "TaskDefinition": {"Ref": "BlueTaskDefinition"}, "LoadBalancers": [ { "ContainerName": "DemoApp", "ContainerPort": 80, "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"}, "AdvancedConfiguration": { "AlternateTargetGroupArn": {"Ref": "ALBTargetGroupGreen"}, "ProductionListenerRule": {"Ref": "ALBListenerProdRule"}, "RoleArn": {"Fn::GetAtt": ["ECSInfrastructureRoleForLoadBalancers", "Arn"]} } } ] } } } }