Esempio di modello di implementazione blu/verde - AWS CloudFormation

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Esempio di modello di implementazione blu/verde

Il modello di esempio seguente imposta una distribuzione CodeDeploy blu/verde attivaECS, con un avanzamento del routing del traffico del 15% per fase e un periodo di stabilizzazione di 5 minuti tra ogni passaggio.

La creazione di uno stack con il modello fornirà la configurazione iniziale della distribuzione. Se in seguito sono state apportate modifiche alle proprietà della BlueTaskSet risorsa che richiedono la sostituzione di tale risorsa, CloudFormation avvierà una distribuzione ecologica come parte dell'aggiornamento dello stack.

JSON

{ "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" ] } } } } }

YAML

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: !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: !GetAtt - BlueTaskSet - Id