翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
で AWS CloudFormation Infrastructure as Code ファイルを使用する方法について説明します AWS Proton。 AWS CloudFormation は、 AWS リソースのモデル化とセットアップに役立つ Infrastructure as Code (IaC ) サービスです。テンプレートでインフラストラクチャリソースを定義します。parametrization. AWS Proton expands パラメータの CloudFormation テンプレートファイル形式の上に Jinja を使用して、定義されたリソースを CloudFormation スタックとしてレンダリング CloudFormation CloudFormation します。詳細については、 『 AWS CloudFormation ユーザーガイド』の「AWS CloudFormationとは?」を参照してください。
AWS Proton は CloudFormation IaC の AWSマネージドプロビジョニングをサポートしています。
既存の独自の Infrastructure as Code (IaC) ファイルから開始する
で使用するために、独自の既存の Infrastructure as Code (IaC) ファイルを適応させることができます AWS Proton。
次の AWS CloudFormation 例、例 1 と例 2 は、独自の既存の CloudFormation IaC ファイルを表します。 CloudFormation はこれらのファイルを使用して 2 つの異なる CloudFormationスタックを作成できます。
例 1 では、 CloudFormation IaC ファイルはコンテナアプリケーション間で共有されるインフラストラクチャをプロビジョニングするように設定されています。この例では、同じ IaC ファイルでプロビジョニングされたインフラストラクチャの複数のセットを作成できるように、入力パラメータを追加しています。各セットには、異なる名前と、VPC およびサブネット CIDR 値のセットを指定できます。管理者またはデベロッパーは、IaC ファイルを使用して でインフラストラクチャリソースをプロビジョニングするときに、これらのパラメータの値を指定します CloudFormation。便宜上、これらの入力パラメータはコメント行のマークが付いており、例では複数回参照されています。出力は、テンプレートの終わりで定義されます。これらは他の CloudFormation IaC ファイルで参照できます。
例 2 では、 CloudFormation IaC ファイルは、例 1 からプロビジョニングされたインフラストラクチャにアプリケーションをデプロイするように設定されています。便宜上、パラメータはコメント化されています。
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS Fargate cluster running containers in a public subnet. Only supports
public facing load balancer, and public service discovery namespaces.
Parameters:
VpcCIDR: # input parameter
Description: CIDR for VPC
Type: String
Default: "10.0.0.0/16"
SubnetOneCIDR: # input parameter
Description: CIDR for SubnetOne
Type: String
Default: "10.0.0.0/24"
SubnetTwoCIDR: # input parameters
Description: CIDR for SubnetTwo
Type: String
Default: "10.0.1.0/24"
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
EnableDnsSupport: true
EnableDnsHostnames: true
CidrBlock:
Ref: 'VpcCIDR'
# Two public subnets, where containers will have public IP addresses
PublicSubnetOne:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock:
Ref: 'SubnetOneCIDR'
MapPublicIpOnLaunch: true
PublicSubnetTwo:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock:
Ref: 'SubnetTwoCIDR'
MapPublicIpOnLaunch: true
# Setup networking resources for the public subnets. Containers
# in the public subnets have public IP addresses and the routing table
# sends network traffic via the internet gateway.
InternetGateway:
Type: AWS::EC2::InternetGateway
GatewayAttachement:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref 'VPC'
InternetGatewayId: !Ref 'InternetGateway'
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref 'VPC'
PublicRoute:
Type: AWS::EC2::Route
DependsOn: GatewayAttachement
Properties:
RouteTableId: !Ref 'PublicRouteTable'
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref 'InternetGateway'
PublicSubnetOneRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetOne
RouteTableId: !Ref PublicRouteTable
PublicSubnetTwoRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetTwo
RouteTableId: !Ref PublicRouteTable
# ECS Resources
ECSCluster:
Type: AWS::ECS::Cluster
# A security group for the containers we will run in Fargate.
# Rules are added to this security group based on what ingress you
# add for the cluster.
ContainerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the Fargate containers
VpcId: !Ref 'VPC'
# This is a role which is used by the ECS tasks themselves.
ECSTaskExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [ecs-tasks.amazonaws.com]
Action: ['sts:AssumeRole']
Path: /
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
# These output values will be available to other templates to use.
Outputs:
ClusterName: # output
Description: The name of the ECS cluster
Value: !Ref 'ECSCluster'
Export:
Name:
Fn::Sub: "${AWS::StackName}-ECSCluster"
ECSTaskExecutionRole: # output
Description: The ARN of the ECS role
Value: !GetAtt 'ECSTaskExecutionRole.Arn'
Export:
Name:
Fn::Sub: "${AWS::StackName}-ECSTaskExecutionRole"
VpcId: # output
Description: The ID of the VPC that this stack is deployed in
Value: !Ref 'VPC'
Export:
Name:
Fn::Sub: "${AWS::StackName}-VPC"
PublicSubnetOne: # output
Description: Public subnet one
Value: !Ref 'PublicSubnetOne'
Export:
Name:
Fn::Sub: "${AWS::StackName}-PublicSubnetOne"
PublicSubnetTwo: # output
Description: Public subnet two
Value: !Ref 'PublicSubnetTwo'
Export:
Name:
Fn::Sub: "${AWS::StackName}-PublicSubnetTwo"
ContainerSecurityGroup: # output
Description: A security group used to allow Fargate containers to receive traffic
Value: !Ref 'ContainerSecurityGroup'
Export:
Name:
Fn::Sub: "${AWS::StackName}-ContainerSecurityGroup"
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy a service on AWS Fargate, hosted in a public subnet, and accessible via a public load balancer.
Parameters:
ContainerPortInput: # input parameter
Description: The port to route traffic to
Type: Number
Default: 80
TaskCountInput: # input parameter
Description: The default number of Fargate tasks you want running
Type: Number
Default: 1
TaskSizeInput: # input parameter
Description: The size of the task you want to run
Type: String
Default: x-small
ContainerImageInput: # input parameter
Description: The name/url of the container image
Type: String
Default: "public.ecr.aws/z9d2n7e1/nginx:1.19.5"
TaskNameInput: # input parameter
Description: Name for your task
Type: String
Default: "my-fargate-instance"
StackName: # input parameter
Description: Name of the environment stack to deploy to
Type: String
Default: "my-fargate-environment"
Mappings:
TaskSizeMap:
x-small:
cpu: 256
memory: 512
small:
cpu: 512
memory: 1024
medium:
cpu: 1024
memory: 2048
large:
cpu: 2048
memory: 4096
x-large:
cpu: 4096
memory: 8192
Resources:
# A log group for storing the stdout logs from this service's containers
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName:
Ref: 'TaskNameInput' # input parameter
# The task definition. This is a simple metadata description of what
# container to run, and what resource requirements it has.
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref 'TaskNameInput'
Cpu: !FindInMap [TaskSizeMap, !Ref 'TaskSizeInput', cpu]
Memory: !FindInMap [TaskSizeMap, !Ref 'TaskSizeInput', memory]
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ExecutionRoleArn:
Fn::ImportValue:
!Sub "${StackName}-ECSTaskExecutionRole" # output parameter from another CloudFormation template
awslogs-region: !Ref 'AWS::Region'
awslogs-stream-prefix: !Ref 'TaskNameInput'
# The service_instance. The service is a resource which allows you to run multiple
# copies of a type of task, and gather up their logs and metrics, as well
# as monitor the number of running tasks and replace any that have crashed
Service:
Type: AWS::ECS::Service
DependsOn: LoadBalancerRule
Properties:
ServiceName: !Ref 'TaskNameInput'
Cluster:
Fn::ImportValue:
!Sub "${StackName}-ECSCluster" # output parameter from another CloudFormation template
LaunchType: FARGATE
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 75
DesiredCount: !Ref 'TaskCountInput'
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- Fn::ImportValue:
!Sub "${StackName}-ContainerSecurityGroup" # output parameter from another CloudFormation template
Subnets:
- Fn::ImportValue:r CloudFormation template
TaskRoleArn: !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'TaskNameInput'
Cpu: !FindInMap [TaskSizeMap, !Ref 'TaskSizeInput', cpu]
Memory: !FindInMap [TaskSizeMap, !Ref 'TaskSizeInput', memory]
Image: !Ref 'ContainerImageInput' # input parameter
PortMappings:
- ContainerPort: !Ref 'ContainerPortInput' # input parameter
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Ref 'TaskNameInput'
!Sub "${StackName}-PublicSubnetOne" # output parameter from another CloudFormation template
- Fn::ImportValue:
!Sub "${StackName}-PublicSubnetTwo" # output parameter from another CloudFormation template
TaskDefinition: !Ref 'TaskDefinition'
LoadBalancers:
- ContainerName: !Ref 'TaskNameInput'
ContainerPort: !Ref 'ContainerPortInput' # input parameter
TargetGroupArn: !Ref 'TargetGroup'
# A target group. This is used for keeping track of all the tasks, and
# what IP addresses / port numbers they have. You can query it yourself,
# to use the addresses yourself, but most often this target group is just
# connected to an application load balancer, or network load balancer, so
# it can automatically distribute traffic across all the targets.
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
TargetType: ip
Name: !Ref 'TaskNameInput'
Port: !Ref 'ContainerPortInput'
Protocol: HTTP
UnhealthyThresholdCount: 2
VpcId:
Fn::ImportValue:
!Sub "${StackName}-VPC" # output parameter from another CloudFormation template
# Create a rule on the load balancer for routing traffic to the target group
LoadBalancerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- TargetGroupArn: !Ref 'TargetGroup'
Type: 'forward'
Conditions:
- Field: path-pattern
Values:
- '*'
ListenerArn: !Ref PublicLoadBalancerListener
Priority: 1
# Enable autoscaling for this service
ScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
DependsOn: Service
Properties:
ServiceNamespace: 'ecs'
ScalableDimension: 'ecs:service:DesiredCount'
ResourceId:
Fn::Join:
- '/'
- - service
- Fn::ImportValue:
!Sub "${StackName}-ECSCluster"
- !Ref 'TaskNameInput'
MinCapacity: 1
MaxCapacity: 10
RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService
# Create scaling policies for the service
ScaleDownPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
DependsOn: ScalableTarget
Properties:
PolicyName:
Fn::Join:
- '/'
- - scale
- !Ref 'TaskNameInput'
- down
PolicyType: StepScaling
ResourceId:
Fn::Join:
- '/'
- - service
- Fn::ImportValue:
!Sub "${StackName}-ECSCluster" # output parameter from another CloudFormation template
- !Ref 'TaskNameInput'
ScalableDimension: 'ecs:service:DesiredCount'
ServiceNamespace: 'ecs'
StepScalingPolicyConfiguration:
AdjustmentType: 'ChangeInCapacity'
StepAdjustments:
- MetricIntervalUpperBound: 0
ScalingAdjustment: -1
MetricAggregationType: 'Average'
Cooldown: 60
ScaleUpPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
DependsOn: ScalableTarget
Properties:
PolicyName:
Fn::Join:
- '/'
- - scale
- !Ref 'TaskNameInput'
- up
PolicyType: StepScaling
ResourceId:
Fn::Join:
- '/'
- - service
- Fn::ImportValue:
!Sub "${StackName}-ECSCluster"
- !Ref 'TaskNameInput'
ScalableDimension: 'ecs:service:DesiredCount'
ServiceNamespace: 'ecs'
StepScalingPolicyConfiguration:
AdjustmentType: 'ChangeInCapacity'
StepAdjustments:
- MetricIntervalLowerBound: 0
MetricIntervalUpperBound: 15
ScalingAdjustment: 1
- MetricIntervalLowerBound: 15
MetricIntervalUpperBound: 25
ScalingAdjustment: 2
- MetricIntervalLowerBound: 25
ScalingAdjustment: 3
MetricAggregationType: 'Average'
Cooldown: 60
# Create alarms to trigger these policies
LowCpuUsageAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName:
Fn::Join:
- '-'
- - low-cpu
- !Ref 'TaskNameInput'
AlarmDescription:
Fn::Join:
- ' '
- - "Low CPU utilization for service"
- !Ref 'TaskNameInput'
MetricName: CPUUtilization
Namespace: AWS/ECS
Dimensions:
- Name: ServiceName
Value: !Ref 'TaskNameInput'
- Name: ClusterName
Value:
Fn::ImportValue:
!Sub "${StackName}-ECSCluster"
Statistic: Average
Period: 60
EvaluationPeriods: 1
Threshold: 20
ComparisonOperator: LessThanOrEqualToThreshold
AlarmActions:
- !Ref ScaleDownPolicy
HighCpuUsageAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName:
Fn::Join:
- '-'
- - high-cpu
- !Ref 'TaskNameInput'
AlarmDescription:
Fn::Join:
- ' '
- - "High CPU utilization for service"
- !Ref 'TaskNameInput'
MetricName: CPUUtilization
Namespace: AWS/ECS
Dimensions:
- Name: ServiceName
Value: !Ref 'TaskNameInput'
- Name: ClusterName
Value:
Fn::ImportValue:
!Sub "${StackName}-ECSCluster"
Statistic: Average
Period: 60
EvaluationPeriods: 1
Threshold: 70
ComparisonOperator: GreaterThanOrEqualToThreshold
AlarmActions:
- !Ref ScaleUpPolicy
EcsSecurityGroupIngressFromPublicALB:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: Ingress from the public ALB
GroupId:
Fn::ImportValue:
!Sub "${StackName}-ContainerSecurityGroup"
IpProtocol: -1
SourceSecurityGroupId: !Ref 'PublicLoadBalancerSG'
# Public load balancer, hosted in public subnets that is accessible
# to the public, and is intended to route traffic to one or more public
# facing services. This is used for accepting traffic from the public
# internet and directing it to public facing microservices
PublicLoadBalancerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the public facing load balancer
VpcId:
Fn::ImportValue:
!Sub "${StackName}-VPC"
SecurityGroupIngress:
# Allow access to ALB from anywhere on the internet
- CidrIp: 0.0.0.0/0
IpProtocol: -1
PublicLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Scheme: internet-facing
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: '30'
Subnets:
# The load balancer is placed into the public subnets, so that traffic
# from the internet can reach the load balancer directly via the internet gateway
- Fn::ImportValue:
!Sub "${StackName}-PublicSubnetOne"
- Fn::ImportValue:
!Sub "${StackName}-PublicSubnetTwo"
SecurityGroups: [!Ref 'PublicLoadBalancerSG']
PublicLoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
DependsOn:
- PublicLoadBalancer
Properties:
DefaultActions:
- TargetGroupArn: !Ref 'TargetGroup'
Type: 'forward'
LoadBalancerArn: !Ref 'PublicLoadBalancer'
Port: 80
Protocol: HTTP
# These output values will be available to other templates to use.
Outputs:
ServiceEndpoint: # output
Description: The URL to access the service
Value: !Sub "http://${PublicLoadBalancer.DNSName}"
これらのファイルは、 で使用するために調整できます AWS Proton。
インフラストラクチャをコードとして に持ち込む AWS Proton
少し変更を加えると、例 1 を が環境をデプロイ AWS Proton するために使用する環境テンプレートバンドルの Infrastructure as Code (IaC ) ファイルとして使用できます (例 3 を参照)。
CloudFormation パラメータを使用する代わりに、Jinja
管理者として、 名前空間を入力 AWS Proton environment.inputs.
パラメータに追加できます。サービス IaC ファイル内で環境 IaC ファイル出力を参照するには、environment.outputs.
名前空間を出力に追加します (たとえば、environment.outputs.ClusterName
)。最後に、中括弧と引用符で囲みます。
これらの変更により、 CloudFormation IaC ファイルを で使用できます AWS Proton。
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS Fargate cluster running containers in a public subnet. Only supports
public facing load balancer, and public service discovery prefixes.
Mappings:
# The VPC and subnet configuration is passed in via the environment spec.
SubnetConfig:
VPC:
CIDR: '{{ environment.inputs.vpc_cidr}}' # input parameter
PublicOne:
CIDR: '{{ environment.inputs.subnet_one_cidr}}' # input parameter
PublicTwo:
CIDR: '{{ environment.inputs.subnet_two_cidr}}' # input parameter
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
EnableDnsSupport: true
EnableDnsHostnames: true
CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR']
# Two public subnets, where containers will have public IP addresses
PublicSubnetOne:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR']
MapPublicIpOnLaunch: true
PublicSubnetTwo:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR']
MapPublicIpOnLaunch: true
# Setup networking resources for the public subnets. Containers
# in the public subnets have public IP addresses and the routing table
# sends network traffic via the internet gateway.
InternetGateway:
Type: AWS::EC2::InternetGateway
GatewayAttachement:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref 'VPC'
InternetGatewayId: !Ref 'InternetGateway'
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref 'VPC'
PublicRoute:
Type: AWS::EC2::Route
DependsOn: GatewayAttachement
Properties:
RouteTableId: !Ref 'PublicRouteTable'
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref 'InternetGateway'
PublicSubnetOneRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetOne
RouteTableId: !Ref PublicRouteTable
PublicSubnetTwoRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetTwo
RouteTableId: !Ref PublicRouteTable
# ECS Resources
ECSCluster:
Type: AWS::ECS::Cluster
# A security group for the containers we will run in Fargate.
# Rules are added to this security group based on what ingress you
# add for the cluster.
ContainerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the Fargate containers
VpcId: !Ref 'VPC'
# This is a role which is used by the ECS tasks themselves.
ECSTaskExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [ecs-tasks.amazonaws.com]
Action: ['sts:AssumeRole']
Path: /
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
# These output values are available to service infrastructure as code files as outputs, when given the
# the 'service_instance.environment.outputs.' namespace, for example, service_instance.environment.outputs.ClusterName.
Outputs:
ClusterName: # output
Description: The name of the ECS cluster
Value: !Ref 'ECSCluster'
ECSTaskExecutionRole: # output
Description: The ARN of the ECS role
Value: !GetAtt 'ECSTaskExecutionRole.Arn'
VpcId: # output
Description: The ID of the VPC that this stack is deployed in
Value: !Ref 'VPC'
PublicSubnetOne: # output
Description: Public subnet one
Value: !Ref 'PublicSubnetOne'
PublicSubnetTwo: # output
Description: Public subnet two
Value: !Ref 'PublicSubnetTwo'
ContainerSecurityGroup: # output
Description: A security group used to allow Fargate containers to receive traffic
Value: !Ref 'ContainerSecurityGroup'
例 1 と例 3 の IaC ファイルは、わずかに異なる CloudFormation スタックを生成します。スタックテンプレートファイルでは、パラメータの表示が異なります。例 1 CloudFormation のスタックテンプレートファイルでは、スタックテンプレートビューにパラメータラベル (キー) が表示されます。例 3 AWS Proton CloudFormation のインフラストラクチャスタックテンプレートファイルには、パラメータ値が表示されます。 AWS Proton 入力パラメータはコンソールスタックパラメータビューに表示されません。 CloudFormation
例 4 では、 AWS Proton サービス IaC ファイルは例 2 に対応します。
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy a service on AWS Fargate, hosted in a public subnet, and accessible via a public load balancer.
Mappings:
TaskSize:
x-small:
cpu: 256
memory: 512
small:
cpu: 512
memory: 1024
medium:
cpu: 1024
memory: 2048
large:
cpu: 2048
memory: 4096
x-large:
cpu: 4096
memory: 8192
Resources:
# A log group for storing the stdout logs from this service's containers
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: '{{service_instance.name}}' # resource parameter
# The task definition. This is a simple metadata description of what
# container to run, and what resource requirements it has.
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: '{{service_instance.name}}'
Cpu: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, cpu] # input parameter
Memory: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, memory]
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ExecutionRoleArn: '{{environment.outputs.ECSTaskExecutionRole}}' # output from an environment infrastructure as code file
TaskRoleArn: !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: '{{service_instance.name}}'
Cpu: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, cpu]
Memory: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, memory]
Image: '{{service_instance.inputs.image}}'
PortMappings:
- ContainerPort: '{{service_instance.inputs.port}}' # input parameter
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: '{{service_instance.name}}'
awslogs-region: !Ref 'AWS::Region'
awslogs-stream-prefix: '{{service_instance.name}}'
# The service_instance. The service is a resource which allows you to run multiple
# copies of a type of task, and gather up their logs and metrics, as well
# as monitor the number of running tasks and replace any that have crashed
Service:
Type: AWS::ECS::Service
DependsOn: LoadBalancerRule
Properties:
ServiceName: '{{service_instance.name}}'
Cluster: '{{environment.outputs.ClusterName}}' # output from an environment infrastructure as code file
LaunchType: FARGATE
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 75
DesiredCount: '{{service_instance.inputs.desired_count}}' # input parameter
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- '{{environment.outputs.ContainerSecurityGroup}}' # output from an environment infrastructure as code file
Subnets:
- '{{environment.outputs.PublicSubnetOne}}' # output from an environment infrastructure as code file
- '{{environment.outputs.PublicSubnetTwo}}'
TaskDefinition: !Ref 'TaskDefinition'
LoadBalancers:
- ContainerName: '{{service_instance.name}}'
ContainerPort: '{{service_instance.inputs.port}}'
TargetGroupArn: !Ref 'TargetGroup'
# A target group. This is used for keeping track of all the tasks, and
# what IP addresses / port numbers they have. You can query it yourself,
# to use the addresses yourself, but most often this target group is just
# connected to an application load balancer, or network load balancer, so
# it can automatically distribute traffic across all the targets.
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
TargetType: ip
Name: '{{service_instance.name}}'
Port: '{{service_instance.inputs.port}}'
Protocol: HTTP
UnhealthyThresholdCount: 2
VpcId: '{{environment.outputs.VpcId}}' # output from an environment infrastructure as code file
# Create a rule on the load balancer for routing traffic to the target group
LoadBalancerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- TargetGroupArn: !Ref 'TargetGroup'
Type: 'forward'
Conditions:
- Field: path-pattern
Values:
- '*'
ListenerArn: !Ref PublicLoadBalancerListener
Priority: 1
# Enable autoscaling for this service
ScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
DependsOn: Service
Properties:
ServiceNamespace: 'ecs'
ScalableDimension: 'ecs:service:DesiredCount'
ResourceId:
Fn::Join:
- '/'
- - service
- '{{environment.outputs.ClusterName}}' # output from an environment infrastructure as code file
- '{{service_instance.name}}'
MinCapacity: 1
MaxCapacity: 10
RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService
# Create scaling policies for the service
ScaleDownPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
DependsOn: ScalableTarget
Properties:
PolicyName:
Fn::Join:
- '/'
- - scale
- '{{service_instance.name}}'
- down
PolicyType: StepScaling
ResourceId:
Fn::Join:
- '/'
- - service
- '{{environment.outputs.ClusterName}}'
- '{{service_instance.name}}'
ScalableDimension: 'ecs:service:DesiredCount'
ServiceNamespace: 'ecs'
StepScalingPolicyConfiguration:
AdjustmentType: 'ChangeInCapacity'
StepAdjustments:
- MetricIntervalUpperBound: 0
ScalingAdjustment: -1
MetricAggregationType: 'Average'
Cooldown: 60
ScaleUpPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
DependsOn: ScalableTarget
Properties:
PolicyName:
Fn::Join:
- '/'
- - scale
- '{{service_instance.name}}'
- up
PolicyType: StepScaling
ResourceId:
Fn::Join:
- '/'
- - service
- '{{environment.outputs.ClusterName}}'
- '{{service_instance.name}}'
ScalableDimension: 'ecs:service:DesiredCount'
ServiceNamespace: 'ecs'
StepScalingPolicyConfiguration:
AdjustmentType: 'ChangeInCapacity'
StepAdjustments:
- MetricIntervalLowerBound: 0
MetricIntervalUpperBound: 15
ScalingAdjustment: 1
- MetricIntervalLowerBound: 15
MetricIntervalUpperBound: 25
ScalingAdjustment: 2
- MetricIntervalLowerBound: 25
ScalingAdjustment: 3
MetricAggregationType: 'Average'
Cooldown: 60
# Create alarms to trigger these policies
LowCpuUsageAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName:
Fn::Join:
- '-'
- - low-cpu
- '{{service_instance.name}}'
AlarmDescription:
Fn::Join:
- ' '
- - "Low CPU utilization for service"
- '{{service_instance.name}}'
MetricName: CPUUtilization
Namespace: AWS/ECS
Dimensions:
- Name: ServiceName
Value: '{{service_instance.name}}'
- Name: ClusterName
Value:
'{{environment.outputs.ClusterName}}'
Statistic: Average
Period: 60
EvaluationPeriods: 1
Threshold: 20
ComparisonOperator: LessThanOrEqualToThreshold
AlarmActions:
- !Ref ScaleDownPolicy
HighCpuUsageAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName:
Fn::Join:
- '-'
- - high-cpu
- '{{service_instance.name}}'
AlarmDescription:
Fn::Join:
- ' '
- - "High CPU utilization for service"
- '{{service_instance.name}}'
MetricName: CPUUtilization
Namespace: AWS/ECS
Dimensions:
- Name: ServiceName
Value: '{{service_instance.name}}'
- Name: ClusterName
Value:
'{{environment.outputs.ClusterName}}'
Statistic: Average
Period: 60
EvaluationPeriods: 1
Threshold: 70
ComparisonOperator: GreaterThanOrEqualToThreshold
AlarmActions:
- !Ref ScaleUpPolicy
EcsSecurityGroupIngressFromPublicALB:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: Ingress from the public ALB
GroupId: '{{environment.outputs.ContainerSecurityGroup}}'
IpProtocol: -1
SourceSecurityGroupId: !Ref 'PublicLoadBalancerSG'
# Public load balancer, hosted in public subnets that is accessible
# to the public, and is intended to route traffic to one or more public
# facing services. This is used for accepting traffic from the public
# internet and directing it to public facing microservices
PublicLoadBalancerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the public facing load balancer
VpcId: '{{environment.outputs.VpcId}}'
SecurityGroupIngress:
# Allow access to ALB from anywhere on the internet
- CidrIp: 0.0.0.0/0
IpProtocol: -1
PublicLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Scheme: internet-facing
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: '30'
Subnets:
# The load balancer is placed into the public subnets, so that traffic
# from the internet can reach the load balancer directly via the internet gateway
- '{{environment.outputs.PublicSubnetOne}}'
- '{{environment.outputs.PublicSubnetTwo}}'
SecurityGroups: [!Ref 'PublicLoadBalancerSG']
PublicLoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
DependsOn:
- PublicLoadBalancer
Properties:
DefaultActions:
- TargetGroupArn: !Ref 'TargetGroup'
Type: 'forward'
LoadBalancerArn: !Ref 'PublicLoadBalancer'
Port: 80
Protocol: HTTP
Outputs:
ServiceEndpoint: # output
Description: The URL to access the service
Value: !Sub "http://${PublicLoadBalancer.DNSName}"
例 5 では、 AWS Proton パイプライン IaC ファイルは、例 4 でプロビジョニングされたサービスインスタンスをサポートするようにパイプラインインフラストラクチャをプロビジョニングします。
Resources:
ECRRepo:
Type: AWS::ECR::Repository
DeletionPolicy: Retain
BuildProject:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
PrivilegedMode: true
Type: LINUX_CONTAINER
EnvironmentVariables:
- Name: repo_name
Type: PLAINTEXT
Value: !Ref ECRRepo
- Name: service_name
Type: PLAINTEXT
Value: '{{ service.name }}' # resource parameter
ServiceRole:
Fn::GetAtt:
- PublishRole
- Arn
Source:
BuildSpec:
Fn::Join:
- ""
- - >-
{
"version": "0.2",
"phases": {
"install": {
"runtime-versions": {
"docker": 18
},
"commands": [
"pip3 install --upgrade --user awscli",
"echo 'f6bd1536a743ab170b35c94ed4c7c4479763356bd543af5d391122f4af852460 yq_linux_amd64' > yq_linux_amd64.sha",
"wget https://github.com/mikefarah/yq/releases/download/3.4.0/yq_linux_amd64",
"sha256sum -c yq_linux_amd64.sha",
"mv yq_linux_amd64 /usr/bin/yq",
"chmod +x /usr/bin/yq"
]
},
"pre_build": {
"commands": [
"cd $CODEBUILD_SRC_DIR",
"$(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)",
"{{ pipeline.inputs.unit_test_command }}", # input parameter
]
},
"build": {
"commands": [
"IMAGE_REPO_NAME=$repo_name",
"IMAGE_TAG=$CODEBUILD_BUILD_NUMBER",
"IMAGE_ID=
- Ref: AWS::AccountId
- >-
.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG",
"docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG -f {{ pipeline.inputs.dockerfile }} .", # input parameter
"docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $IMAGE_ID;",
"docker push $IMAGE_ID"
]
},
"post_build": {
"commands": [
"aws proton --region $AWS_DEFAULT_REGION get-service --name $service_name | jq -r .service.spec > service.yaml",
"yq w service.yaml 'instances[*].spec.image' \"$IMAGE_ID\" > rendered_service.yaml"
]
}
},
"artifacts": {
"files": [
"rendered_service.yaml"
]
}
}
Type: CODEPIPELINE
EncryptionKey:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
{% for service_instance in service_instances %}
Deploy{{loop.index}}Project:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
PrivilegedMode: false
Type: LINUX_CONTAINER
EnvironmentVariables:
- Name: service_name
Type: PLAINTEXT
Value: '{{service.name}}' # resource parameter
- Name: service_instance_name
Type: PLAINTEXT
Value: '{{service_instance.name}}' # resource parameter
ServiceRole:
Fn::GetAtt:
- DeploymentRole
- Arn
Source:
BuildSpec: >-
{
"version": "0.2",
"phases": {
"build": {
"commands": [
"pip3 install --upgrade --user awscli",
"aws proton --region $AWS_DEFAULT_REGION update-service-instance --deployment-type CURRENT_VERSION --name $service_instance_name --service-name $service_name --spec file://rendered_service.yaml",
"aws proton --region $AWS_DEFAULT_REGION wait service-instance-deployed --name $service_instance_name --service-name $service_name"
]
}
}
}
Type: CODEPIPELINE
EncryptionKey:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
{% endfor %}
# This role is used to build and publish an image to ECR
PublishRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Version: "2012-10-17"
PublishRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource:
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":logs:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :log-group:/aws/codebuild/
- Ref: BuildProject
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":logs:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :log-group:/aws/codebuild/
- Ref: BuildProject
- :*
- Action:
- codebuild:CreateReportGroup
- codebuild:CreateReport
- codebuild:UpdateReport
- codebuild:BatchPutTestCases
Effect: Allow
Resource:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":codebuild:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :report-group/
- Ref: BuildProject
- -*
- Action:
- ecr:GetAuthorizationToken
Effect: Allow
Resource: "*"
- Action:
- ecr:BatchCheckLayerAvailability
- ecr:CompleteLayerUpload
- ecr:GetAuthorizationToken
- ecr:InitiateLayerUpload
- ecr:PutImage
- ecr:UploadLayerPart
Effect: Allow
Resource:
Fn::GetAtt:
- ECRRepo
- Arn
- Action:
- proton:GetService
Effect: Allow
Resource: "*"
- Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
- s3:DeleteObject*
- s3:PutObject*
- s3:Abort*
Effect: Allow
Resource:
- Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- Fn::Join:
- ""
- - Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- /*
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
- Action:
- kms:Decrypt
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
Version: "2012-10-17"
PolicyName: PublishRoleDefaultPolicy
Roles:
- Ref: PublishRole
DeploymentRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Version: "2012-10-17"
DeploymentRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource:
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":logs:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :log-group:/aws/codebuild/Deploy*Project*
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":logs:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :log-group:/aws/codebuild/Deploy*Project:*
- Action:
- codebuild:CreateReportGroup
- codebuild:CreateReport
- codebuild:UpdateReport
- codebuild:BatchPutTestCases
Effect: Allow
Resource:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":codebuild:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :report-group/Deploy*Project
- -*
- Action:
- proton:UpdateServiceInstance
- proton:GetServiceInstance
Effect: Allow
Resource: "*"
- Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
Effect: Allow
Resource:
- Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- Fn::Join:
- ""
- - Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- /*
- Action:
- kms:Decrypt
- kms:DescribeKey
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
- Action:
- kms:Decrypt
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
Version: "2012-10-17"
PolicyName: DeploymentRoleDefaultPolicy
Roles:
- Ref: DeploymentRole
PipelineArtifactsBucketEncryptionKey:
Type: AWS::KMS::Key
Properties:
KeyPolicy:
Statement:
- 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
- kms:GenerateDataKey
- kms:TagResource
- kms:UntagResource
Effect: Allow
Principal:
AWS:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":iam::"
- Ref: AWS::AccountId
- :root
Resource: "*"
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS:
Fn::GetAtt:
- PipelineRole
- Arn
Resource: "*"
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS:
Fn::GetAtt:
- PublishRole
- Arn
Resource: "*"
- Action:
- kms:Decrypt
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS:
Fn::GetAtt:
- PublishRole
- Arn
Resource: "*"
- Action:
- kms:Decrypt
- kms:DescribeKey
Effect: Allow
Principal:
AWS:
Fn::GetAtt:
- DeploymentRole
- Arn
Resource: "*"
- Action:
- kms:Decrypt
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS:
Fn::GetAtt:
- DeploymentRole
- Arn
Resource: "*"
Version: "2012-10-17"
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
PipelineArtifactsBucket:
Type: AWS::S3::Bucket
Properties:
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
KMSMasterKeyID:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
SSEAlgorithm: aws:kms
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
UpdateReplacePolicy: Retain
DeletionPolicy: Retain
PipelineArtifactsBucketEncryptionKeyAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: 'alias/codepipeline-encryption-key-{{ service.name }}'
TargetKeyId:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
PipelineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Version: "2012-10-17"
PipelineRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
- s3:DeleteObject*
- s3:PutObject*
- s3:Abort*
Effect: Allow
Resource:
- Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- Fn::Join:
- ""
- - Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- /*
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
- Action: codestar-connections:*
Effect: Allow
Resource: "*"
- Action: sts:AssumeRole
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineBuildCodePipelineActionRole
- Arn
- Action: sts:AssumeRole
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineDeployCodePipelineActionRole
- Arn
Version: "2012-10-17"
PolicyName: PipelineRoleDefaultPolicy
Roles:
- Ref: PipelineRole
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn:
Fn::GetAtt:
- PipelineRole
- Arn
Stages:
- Actions:
- ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeStarSourceConnection
Version: "1"
Configuration:
ConnectionArn: '{{ service.repository_connection_arn }}'
FullRepositoryId: '{{ service.repository_id }}'
BranchName: '{{ service.branch_name }}'
Name: Checkout
OutputArtifacts:
- Name: Artifact_Source_Checkout
RunOrder: 1
Name: Source
- Actions:
- ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: "1"
Configuration:
ProjectName:
Ref: BuildProject
InputArtifacts:
- Name: Artifact_Source_Checkout
Name: Build
OutputArtifacts:
- Name: BuildOutput
RoleArn:
Fn::GetAtt:
- PipelineBuildCodePipelineActionRole
- Arn
RunOrder: 1
Name: Build {%- for service_instance in service_instances %}
- Actions:
- ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: "1"
Configuration:
ProjectName:
Ref: Deploy{{loop.index}}Project
InputArtifacts:
- Name: BuildOutput
Name: Deploy
RoleArn:
Fn::GetAtt:
- PipelineDeployCodePipelineActionRole
- Arn
RunOrder: 1
Name: 'Deploy{{service_instance.name}}'
{%- endfor %}
ArtifactStore:
EncryptionKey:
Id:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
Type: KMS
Location:
Ref: PipelineArtifactsBucket
Type: S3
DependsOn:
- PipelineRoleDefaultPolicy
- PipelineRole
PipelineBuildCodePipelineActionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":iam::"
- Ref: AWS::AccountId
- :root
Version: "2012-10-17"
PipelineBuildCodePipelineActionRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
- codebuild:StopBuild
Effect: Allow
Resource:
Fn::GetAtt:
- BuildProject
- Arn
Version: "2012-10-17"
PolicyName: PipelineBuildCodePipelineActionRoleDefaultPolicy
Roles:
- Ref: PipelineBuildCodePipelineActionRole
PipelineDeployCodePipelineActionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":iam::"
- Ref: AWS::AccountId
- :root
Version: "2012-10-17"
PipelineDeployCodePipelineActionRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
- codebuild:StopBuild
Effect: Allow
Resource:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":codebuild:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- ":project/Deploy*"
Version: "2012-10-17"
PolicyName: PipelineDeployCodePipelineActionRoleDefaultPolicy
Roles:
- Ref: PipelineDeployCodePipelineActionRole
Outputs:
PipelineEndpoint:
Description: The URL to access the pipeline
Value: !Sub "https://${AWS::Region}.console.aws.amazon.com/codesuite/codepipeline/pipelines/${Pipeline}/view?region=${AWS::Region}"
]
}
}
}
Type: CODEPIPELINE
EncryptionKey:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
{% endfor %}
# This role is used to build and publish an image to ECR
PublishRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Version: "2012-10-17"
PublishRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource:
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":logs:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :log-group:/aws/codebuild/
- Ref: BuildProject
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":logs:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :log-group:/aws/codebuild/
- Ref: BuildProject
- :*
- Action:
- codebuild:CreateReportGroup
- codebuild:CreateReport
- codebuild:UpdateReport
- codebuild:BatchPutTestCases
Effect: Allow
Resource:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":codebuild:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :report-group/
- Ref: BuildProject
- -*
- Action:
- ecr:GetAuthorizationToken
Effect: Allow
Resource: "*"
- Action:
- ecr:BatchCheckLayerAvailability
- ecr:CompleteLayerUpload
- ecr:GetAuthorizationToken
- ecr:InitiateLayerUpload
- ecr:PutImage
- ecr:UploadLayerPart
Effect: Allow
Resource:
Fn::GetAtt:
- ECRRepo
- Arn
- Action:
- proton:GetService
Effect: Allow
Resource: "*"
- Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
- s3:DeleteObject*
- s3:PutObject*
- s3:Abort*
Effect: Allow
Resource:
- Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- Fn::Join:
- ""
- - Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- /*
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
- Action:
- kms:Decrypt
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
Version: "2012-10-17"
PolicyName: PublishRoleDefaultPolicy
Roles:
- Ref: PublishRole
DeploymentRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Version: "2012-10-17"
DeploymentRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource:
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":logs:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :log-group:/aws/codebuild/Deploy*Project*
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":logs:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :log-group:/aws/codebuild/Deploy*Project:*
- Action:
- codebuild:CreateReportGroup
- codebuild:CreateReport
- codebuild:UpdateReport
- codebuild:BatchPutTestCases
Effect: Allow
Resource:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":codebuild:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- :report-group/Deploy*Project
- -*
- Action:
- proton:UpdateServiceInstance
- proton:GetServiceInstance
Effect: Allow
Resource: "*"
- Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
Effect: Allow
Resource:
- Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- Fn::Join:
- ""
- - Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- /*
- Action:
- kms:Decrypt
- kms:DescribeKey
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
- Action:
- kms:Decrypt
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
Version: "2012-10-17"
PolicyName: DeploymentRoleDefaultPolicy
Roles:
- Ref: DeploymentRole
PipelineArtifactsBucketEncryptionKey:
Type: AWS::KMS::Key
Properties:
KeyPolicy:
Statement:
- 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
- kms:GenerateDataKey
- kms:TagResource
- kms:UntagResource
Effect: Allow
Principal:
AWS:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":iam::"
- Ref: AWS::AccountId
- :root
Resource: "*"
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS:
Fn::GetAtt:
- PipelineRole
- Arn
Resource: "*"
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS:
Fn::GetAtt:
- PublishRole
- Arn
Resource: "*"
- Action:
- kms:Decrypt
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS:
Fn::GetAtt:
- PublishRole
- Arn
Resource: "*"
- Action:
- kms:Decrypt
- kms:DescribeKey
Effect: Allow
Principal:
AWS:
Fn::GetAtt:
- DeploymentRole
- Arn
Resource: "*"
- Action:
- kms:Decrypt
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS:
Fn::GetAtt:
- DeploymentRole
- Arn
Resource: "*"
Version: "2012-10-17"
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
PipelineArtifactsBucket:
Type: AWS::S3::Bucket
Properties:
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
KMSMasterKeyID:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
SSEAlgorithm: aws:kms
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
UpdateReplacePolicy: Retain
DeletionPolicy: Retain
PipelineArtifactsBucketEncryptionKeyAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: 'alias/codepipeline-encryption-key-{{ service.name }}' # resource parameter
TargetKeyId:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
PipelineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Version: "2012-10-17"
PipelineRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
- s3:DeleteObject*
- s3:PutObject*
- s3:Abort*
Effect: Allow
Resource:
- Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- Fn::Join:
- ""
- - Fn::GetAtt:
- PipelineArtifactsBucket
- Arn
- /*
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
- Action: codestar-connections:*
Effect: Allow
Resource: "*"
- Action: sts:AssumeRole
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineBuildCodePipelineActionRole
- Arn
- Action: sts:AssumeRole
Effect: Allow
Resource:
Fn::GetAtt:
- PipelineDeployCodePipelineActionRole
- Arn
Version: "2012-10-17"
PolicyName: PipelineRoleDefaultPolicy
Roles:
- Ref: PipelineRole
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn:
Fn::GetAtt:
- PipelineRole
- Arn
Stages:
- Actions:
- ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeStarSourceConnection
Version: "1"
Configuration:
ConnectionArn: '{{ service.repository_connection_arn }}' # resource parameter
FullRepositoryId: '{{ service.repository_id }}' # resource parameter
BranchName: '{{ service.branch_name }}' # resource parameter
Name: Checkout
OutputArtifacts:
- Name: Artifact_Source_Checkout
RunOrder: 1
Name: Source
- Actions:
- ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: "1"
Configuration:
ProjectName:
Ref: BuildProject
InputArtifacts:
- Name: Artifact_Source_Checkout
Name: Build
OutputArtifacts:
- Name: BuildOutput
RoleArn:
Fn::GetAtt:
- PipelineBuildCodePipelineActionRole
- Arn
RunOrder: 1
Name: Build {%- for service_instance in service_instances %}
- Actions:
- ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: "1"
Configuration:
ProjectName:
Ref: Deploy{{loop.index}}Project
InputArtifacts:
- Name: BuildOutput
Name: Deploy
RoleArn:
Fn::GetAtt:
- PipelineDeployCodePipelineActionRole
- Arn
RunOrder: 1
Name: 'Deploy{{service_instance.name}}' # resource parameter
{%- endfor %}
ArtifactStore:
EncryptionKey:
Id:
Fn::GetAtt:
- PipelineArtifactsBucketEncryptionKey
- Arn
Type: KMS
Location:
Ref: PipelineArtifactsBucket
Type: S3
DependsOn:
- PipelineRoleDefaultPolicy
- PipelineRole
PipelineBuildCodePipelineActionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":iam::"
- Ref: AWS::AccountId
- :root
Version: "2012-10-17"
PipelineBuildCodePipelineActionRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
- codebuild:StopBuild
Effect: Allow
Resource:
Fn::GetAtt:
- BuildProject
- Arn
Version: "2012-10-17"
PolicyName: PipelineBuildCodePipelineActionRoleDefaultPolicy
Roles:
- Ref: PipelineBuildCodePipelineActionRole
PipelineDeployCodePipelineActionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":iam::"
- Ref: AWS::AccountId
- :root
Version: "2012-10-17"
PipelineDeployCodePipelineActionRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
- codebuild:StopBuild
Effect: Allow
Resource:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":codebuild:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- ":project/Deploy*"
Version: "2012-10-17"
PolicyName: PipelineDeployCodePipelineActionRoleDefaultPolicy
Roles:
- Ref: PipelineDeployCodePipelineActionRole
Outputs:
PipelineEndpoint:
Description: The URL to access the pipeline
Value: !Sub "https://${AWS::Region}.console.aws.amazon.com/codesuite/codepipeline/pipelines/${Pipeline}/view?region=${AWS::Region}"