😸
【CloudFormation】EventBridgeからECSタスクを起動するテンプレート
1. はじめに
こんにちわ、Mitsuoです。
今回はCloudFormationを用いてEventBridgeからECSタスクを起動する環境を構築してみました。
2. 概要
流れは以下の通りです。
- S3バケットにオブジェクトを格納する
- オブジェクトの格納を契機にEventBridgeルールが起動する
- ターゲットのECSタスクを実行する
3. 作成するリソース
- 作成する主なリソースは以下の通り
- VPC × 1
- Private Subnet × 2
- NetworkACL × 2
- Route Table × 2
- IAMロール × 3 (ECS用に2つ、EventBridge用に1つ)
- IAMポリシー × 3 (ECS用に2つ、EventBridge用に1つ)
- Security Group × 3 (CloudWatch LogsおよびECRのVPCEndPoint用)
- EFS × 1
- マウントターゲット × 2
- VPCEndpoint × 3 (Interface型のECRおよびCloudWatch Logsへのアクセス用)
- VPCEndpoint × 1 (Gateway型のS3へのアクセス用)
- EventBridgeルール × 1
- ECSクラスター × 1
- ECSタスク定義 × 1
など
3.1 補足
- ブログの範囲では利用しないが、ECSのボリュームはEFSを指定する
- プライベートサブネット配下でECSタスクを実行する
- VPCエンドポイント経由でECRおよびCloudWatch Logsエンドポイントにアクセスする
4. 環境構築
CloudFormationを用いて、次の順で環境構築を行う。
- ネットワーク環境を作成
- S3バケットを作成
- ECRリポジトリを作成
- VPCエンドポイントとセキュリティグループ、ECS用のIAMロールを作成
- ECS、EFS、CloudWatch Logsを作成
- EventBridgeルール、ルール用のIAMロールを作成
4.1 ネットワーク環境を作成
以下の情報を基にスタックを作成する。
パラメータ値:
項目 | 備考 |
---|---|
SystemName |
プロジェクト名や利用目的等を入力する |
EnvType |
デプロイする環境を選択する 検証、ステージング、本番の3点 |
Tagprefix |
任意で入力するPrefix値を指定する |
Owner |
作業者、所有者、コスト管理用に入力する |
VPCCIDR |
作成するVPCのCIDRを指定する |
PrivateSubnet1CIDR |
作成するVPC配下のサブネットCIDRを指定する |
PrivateSubnet2CIDR |
作成するVPC配下のサブネットCIDRを指定する |
4.1.1 テンプレート情報
AWSTemplateFormatVersion: 2010-09-09
Description: Deploy a VPC and related resources such as Subnet, Route Table.
# ------------------------------------------------------------#
# Caution:
# This template is for deploying resources in Tokyo region(ap-northeast-1).
# If you deploy them in another region, make sure that you understand below content and make modification for parameters such as AvailabilityZone.
# ------------------------------------------------------------#
# Metadata:
# This can privide details about the template.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html.
# As Metadata Keys, AWS::CloudFormation::Interface can Defines the grouping and ordering of input parameters
# when they are displayed in the AWS CloudFormation console.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-interface.html.
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
-
Parameters:
- SystemName
- EnvType
- Tagprefix
- Owner
- VPCCIDR
- PrivateSubnet1CIDR
- PrivateSubnet2CIDR
ParameterLabels:
SystemName:
default: "SystemName:Type the Systemname"
EnvType:
default: "EnvType: Select the environment to which you want to deploy resources"
Tagprefix:
default: "Tagprefix: Type the Tagprefix which is logical unit name about this stack(e.g. Webserver,Monitoring,Logging)"
Owner:
default: "Owner: Type who owns these resources (e.g. project name or worker, whether this purpose is just verification or not)"
VPCCIDR:
default: "VPCCIDR: Type VPC's CIDR such as NN.NN.NN.NN/NN based on RFC 1918"
PrivateSubnet1CIDR:
default: "PrivateSubnet1CIDR: Type your subnet's CIDR in AZ-A such as NN.NN.NN.NN/NN based on RFC 1918"
PrivateSubnet2CIDR:
default: "PrivateSubnet2CIDR: Type your subnet's CIDR in AZ-C such as NN.NN.NN.NN/NN based on RFC 1918"
# ------------------------------------------------------------#
# Parameters
# This Can enable templates to input custom values each time you create or update a stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html.
# ------------------------------------------------------------#
Parameters:
SystemName:
Type: String
EnvType:
Type: String
Default: "dev"
AllowedValues:
- dev
- stg
- prd
Tagprefix:
Type: String
Owner:
Type: String
VPCCIDR:
Type: String
Default: "10.0.0.0/16"
ConstraintDescription: "Type VPC's CIDR such as NN.NN.NN.NN/NN based on RFC 1918"
PrivateSubnet1CIDR:
Type: String
Default: "10.0.50.0/24"
ConstraintDescription: "Type your subnet's CIDR in AZ-A such as NN.NN.NN.NN/NN based on RFC 1918"
PrivateSubnet2CIDR:
Type: String
Default: "10.0.100.0/24"
ConstraintDescription: "Type your subnet's CIDR in AZ-C such as NN.NN.NN.NN/NN based on RFC 1918"
# ------------------------------------------------------------#
# Resources
# This can declare the AWS resources that you want to include in the stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Resources:
# ------------------------------------------------------------#
# Create VPC
# ------------------------------------------------------------#
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCIDR
EnableDnsHostnames: "true"
EnableDnsSupport: "true"
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-VPC
- Key: Owner
Value: !Ref Owner
# ------------------------------------------------------------#
# Create PrivateSubnet
# ------------------------------------------------------------#
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnet1CIDR
AvailabilityZone: ap-northeast-1a
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-PrivateSubnet-1a
- Key: Owner
Value: !Ref Owner
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnet2CIDR
AvailabilityZone: ap-northeast-1c
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-PrivateSubnet-1c
- Key: Owner
Value: !Ref Owner
# ------------------------------------------------------------#
# Create NetworkACL and associate NetworkACL with each Subnet
# ------------------------------------------------------------#
NetworkACL1:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-Networkacl-1a
- Key: Owner
Value: !Ref Owner
NetworkACLAssoc1:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
NetworkAclId: !Ref NetworkACL1
SubnetId: !Ref PrivateSubnet1
NetworkACL2:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-Networkacl-1c
- Key: Owner
Value: !Ref Owner
NetworkACLAssoc2:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
NetworkAclId: !Ref NetworkACL2
SubnetId: !Ref PrivateSubnet2
# ------------------------------------------------------------#
# Add In/Outbound Rule to NetworkACL
# ------------------------------------------------------------#
NaclInboundRule1:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref NetworkACL1
RuleNumber: 100
Protocol: -1
Egress: false
RuleAction: allow
CidrBlock: 0.0.0.0/0
NaclOutboundRule1:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref NetworkACL1
RuleNumber: 100
Protocol: -1
Egress: true
RuleAction: allow
CidrBlock: 0.0.0.0/0
NaclInboundRule2:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref NetworkACL2
RuleNumber: 100
Protocol: -1
Egress: false
RuleAction: allow
CidrBlock: 0.0.0.0/0
NaclOutboundRule2:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref NetworkACL2
RuleNumber: 100
Protocol: -1
Egress: true
RuleAction: allow
CidrBlock: 0.0.0.0/0
# ------------------------------------------------------------#
# Create Route Table and associate with Private Subnet
# ------------------------------------------------------------#
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-RouteTable-PrivateSubnet-1a
- Key: Owner
Value: !Ref Owner
PrivateSubnetRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet1
RouteTableId: !Ref PrivateRouteTable1
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-RouteTable-PrivateSubnet-1c
- Key: Owner
Value: !Ref Owner
PrivateSubnetRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref PrivateRouteTable2
# ------------------------------------------------------------#
# Specify route in a route table
# Exactly one of [LocalGatewayId, InstanceId, NatGatewayId, TransitGatewayId, VpcEndpointId, GatewayId, NetworkInterfaceId,
# EgressOnlyInternetGatewayId, CarrierGatewayId, VpcPeeringConnectionId] must be specified and not empty.
# ------------------------------------------------------------#
# Route:
# Type: AWS::EC2::Route
# Properties:
# RouteTableId: !Ref PrivateRouteTable
# DestinationCidrBlock: 10.0.0.0/16
# ------------------------------------------------------------#
# Outputs
# This can output each value specified as output section.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Outputs:
VPC:
Description: VPC
Value: !Ref VPC
PrivateSubnet1:
Description: PrivateSubnet1
Value: !Ref PrivateSubnet1
PrivateSubnet2:
Description: PrivateSubnet2
Value: !Ref PrivateSubnet2
NetworkACL1:
Description: NetworkACL1
Value: !Ref NetworkACL1
NetworkACL2:
Description: NetworkACL2
Value: !Ref NetworkACL2
RouteTable1:
Description: RouteTable1
Value: !Ref PrivateRouteTable1
RouteTable2:
Description: RouteTable2
Value: !Ref PrivateRouteTable2
AZ1:
Description: Availability Zone 1
Value: !GetAtt
- PrivateSubnet1
- AvailabilityZone
AZ2:
Description: Availability Zone 2
Value: !GetAtt
- PrivateSubnet2
- AvailabilityZone
4.2 S3バケットを作成
- S3バケットおよびバケットポリシーを作成する
- イベント発火させるためのオブジェクトを配置するS3バケットである
- あくまで検証目的なのでバケットポリシーはとりわけ設定していない、必要に応じてポリシーを書き換えること
- オブジェクトを格納するディレクトリは別途作成する必要あり
以下の情報を基にスタックを作成する。
パラメータ値:
項目 | 備考 |
---|---|
SystemName |
プロジェクト名や利用目的等を入力する |
EnvType |
デプロイする環境を選択する 検証、ステージング、本番の3点 |
Tagprefix |
任意で入力するPrefix値を指定する |
Owner |
作業者、所有者、コスト管理用に入力する |
4.2.1 テンプレート情報
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy S3 Bucket with Bucket policie.
# ------------------------------------------------------------#
# Prerequisite:
# This template is for deploying four Buckets(S3) with Bucket policies.
# ------------------------------------------------------------#
# Metadata:
# This can provide details about the template.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html.
# As Metadata Keys, AWS::CloudFormation::Interface can define the grouping and ordering of input parameters
# when they are displayed in the AWS CloudFormation console.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-interface.html.
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
-
Parameters:
- SystemName
- EnvType
- Tagprefix
- Owner
ParameterLabels:
SystemName:
default: "SystemName: Type your project Name you would like to name"
EnvType:
default: "EnvType: Select which environment you would like to deploy buckets in."
Tagprefix:
default: "Tagprefix: Type the prefix you would like to add as logical unit name about each resource(e.g. webserver,monitoring,logging)"
Owner:
default: "Owner: Type who owns these resources (e.g. project name, worker or for cost management)"
# ------------------------------------------------------------#
# Parameters
# This can enable templates to input custom values each time you create or update a stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html.
# ------------------------------------------------------------#
Parameters:
SystemName:
Type: String
EnvType:
Type: String
Default: "dev"
AllowedValues:
- dev
- stg
- prd
Tagprefix:
Type: String
Owner:
Type: String
# ------------------------------------------------------------#
# Resources
# This can declare the AWS resources that you want to include in the stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Resources:
# ------------------------------------------------------------#
# Create S3 Bucket 1
# ------------------------------------------------------------#
S3Bucket1:
Type: 'AWS::S3::Bucket'
DeletionPolicy: Retain
Properties:
BucketName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-s3bucket-place-object-${AWS::AccountId}
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
VersioningConfiguration:
Status: Suspended
# アクセスログ設定は無効化
# LoggingConfiguration:
# DestinationBucketName: !Ref S3Bucket3
# LogFilePrefix: AccessLog/
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
LifecycleConfiguration:
Rules:
- Id: !Sub ${SystemName}-${EnvType}-${Tagprefix}-Lifecycle-s3bucket-place-object
Status: Enabled
ExpirationInDays: 30
OwnershipControls:
Rules:
- ObjectOwnership: BucketOwnerEnforced
NotificationConfiguration:
EventBridgeConfiguration:
EventBridgeEnabled: true
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-s3bucket-place-object-${AWS::AccountId}
- Key: Owner
Value: !Sub ${Owner}
# ------------------------------------------------------------#
# Create S3 Bucket Policy
# ------------------------------------------------------------#
BucketPolicy1:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref S3Bucket1
PolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- 's3:*'
Sid: BucketPolicy1
Effect: Allow
Resource:
- !Sub 'arn:aws:s3:::${S3Bucket1}'
- !Sub 'arn:aws:s3:::${S3Bucket1}/*'
Principal:
AWS:
- !Sub 'arn:aws:iam::${AWS::AccountId}:root'
DependsOn: S3Bucket1
# ------------------------------------------------------------#
# Outputs
# This can output each value specified as output section.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Outputs:
S3Bucket1:
Description: S3Bucket1
Value: !Ref S3Bucket1
4.3 ECRリポジトリを作成
- ECSからPullするECRリポジトリを作成する
- この手順ではECRにイメージをPushする手順を書いていない
以下の情報を基にスタックを作成する。
パラメータ値:
項目 | 備考 |
---|---|
SystemName |
プロジェクト名や利用目的等を入力する |
EnvType |
デプロイする環境を選択する 検証、ステージング、本番の3点 |
Tagprefix |
任意で入力するPrefix値を指定する |
Owner |
作業者、所有者、コスト管理用に入力する |
4.3.1 テンプレート情報
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy a ECR repository.
# ------------------------------------------------------------#
# Caution:
# This template is for deploying ECR repository.
# Make sure you confirm which the region you set up in advance.
# The building phase is not designated to set up resource based policy.
# So note that we deleted related resources.
# ------------------------------------------------------------#
# Metadata:
# This can privide details about the template.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html.
# As Metadata Keys, AWS::CloudFormation::Interface can Defines the grouping and ordering of input parameters
# when they are displayed in the AWS CloudFormation console.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-interface.html.
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
-
Parameters:
- SystemName
- EnvType
- Tagprefix
- Owner
ParameterLabels:
SystemName:
default: "SystemName: Type the Systemname"
EnvType:
default: "EnvType: Select the environment in which you deploy resources"
Tagprefix:
default: "Tagprefix: Type the Tagprefix which is logical unit name about this stack(e.g. Webserver,Monitoring,Logging)"
Owner:
default: "Owner: Type who owns these resources (e.g. project name or worker, whether this purpose is just verification or not)"
# ------------------------------------------------------------#
# Parameters
# This Can enable templates to input custom values each time you create or update a stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html.
# The building phase is not designated to set up resource based policy.
# So note that we deleted related resources.
# ------------------------------------------------------------#
Parameters:
SystemName:
Type: String
EnvType:
Type: String
Default: "dev"
AllowedValues:
- dev
- stg
- prd
Tagprefix:
Type: String
Owner:
Type: String
# ------------------------------------------------------------#
# Resources
# This can declare the AWS resources that you want to include in the stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Resources:
# ------------------------------------------------------------#
# Create ECR Repository
# The building phase is not designated to set up resource based policy.
# So note that we deleted related configuration .
# ------------------------------------------------------------#
ECRRepository1:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ecr-repository
ImageScanningConfiguration:
ScanOnPush: false
EncryptionConfiguration:
EncryptionType: AES256
ImageTagMutability: IMMUTABLE
LifecyclePolicy:
LifecyclePolicyText: >
{
"rules": [
{
"action": {
"type": "expire"
},
"selection": {
"countType": "imageCountMoreThan",
"countNumber": 5,
"tagStatus": "any"
},
"description": "delete old images more than 5 images",
"rulePriority": 1
}
]
}
RegistryId: !Ref AWS::AccountId
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ecr-repository
- Key: Owner
Value: !Ref Owner
# ------------------------------------------------------------#
# Outputs
# This can output each value specified as output section.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html.
# ------------------------------------------------------------#
Outputs:
ECRRepository1:
Description: ECRRepository1
Value: !Ref ECRRepository1
4.4 VPCエンドポイントとセキュリティグループ、IAMロール(ECS用)を作成
以下の情報を基にスタックを作成する。
パラメータ値:
項目 | 備考 |
---|---|
SystemName |
プロジェクト名や利用目的等を入力する |
EnvType |
デプロイする環境を選択する 検証、ステージング、本番の3点 |
Tagprefix |
任意で入力するPrefix値を指定する |
Owner |
作業者、所有者、コスト管理用に入力する |
VPCID |
作成済みのVPCのID |
VPCCIDR |
作成済みのVPCのCIDR` |
InterfaceSubnetId1 |
作成済みVPCのプライベートサブネット(AZは1a) |
InterfaceSubnetId2 |
作成済みVPCのプライベートサブネット(AZは1c) |
RouteTableId1 |
作成済みVPCのプライベートサブネット(1a)におけるルートテーブルID |
RouteTableId2 |
作成済みVPCのプライベートサブネット(1c)におけるルートテーブルID |
S3BucketName1 |
作成済みのS3バケット名 |
ECRRepositoryName1 |
作成済みのECRリポジトリ名 |
- 作成するロールには、S3に対するアクションなどを書いている
- あくまで例として記載するので、適宜修正すること
4.4.1 テンプレート情報
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy some IAM Role and VPCEndPoint using both Interface(PrivateLink) and Gateway types.
# ------------------------------------------------------------#
# Caution:
# This template is for deploying resources in Tokyo region(ap-northeast-1).
# If you deploy them in another region, make sure that you understand below content and make modification for parameters such as AvailabilityZone.
# This also includes Security Gruops to attach them to endpoints.
# And This makes Security Gruop for instance in VPC network because source configuration for each security gruop need that in advance.
# The building phase is not designated to set up resource based policy.
# So note that we deleted related resources.
# ------------------------------------------------------------#
# Metadata:
# This can privide details about the template.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html.
# As Metadata Keys, AWS::CloudFormation::Interface can Defines the grouping and ordering of input parameters
# when they are displayed in the AWS CloudFormation console.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-interface.html.
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
-
Parameters:
- SystemName
- EnvType
- Tagprefix
- Owner
- VPCCIDR
- VPCID
- InterfaceSubnetId1
- InterfaceSubnetId2
- RouteTableId1
- RouteTableId2
- S3BucketName1
- ECRRepositoryName1
ParameterLabels:
SystemName:
default: "SystemName: Type the Systemname"
EnvType:
default: "EnvType: Select the environment in which you deploy resources"
Tagprefix:
default: "Tagprefix: Type the Tagprefix which is logical unit name about this stack(e.g. Webserver,Monitoring,Logging)"
Owner:
default: "Owner: Type who owns these resources (e.g. project name or worker, whether this purpose is just verification or not)"
VPCID:
default: "VPCID: Select the VPC ID"
VPCCIDR:
default: "VPCCIDR: This is for deciding Security Group Ingress CIDR for instance in VPC. Type VPC's CIDR such as NN.NN.NN.NN/NN based on RFC 1918."
InterfaceSubnetId1:
default: "InterfaceSubnetId1: Select private subnet-1a associated with VPC Endpoints(Interface Type)"
InterfaceSubnetId2:
default: "InterfaceSubnetId2: Select private subnet-1c associated with VPC Endpoints(Interface Type)"
RouteTableId1:
default: "RouteTableId1: Type your RouteTableId for private subnet-1a associated with VPC Endpoints(Gateway Type)."
RouteTableId2:
default: "RouteTableId2: Type your RouteTableId for private subnet-1c associated with VPC Endpoints(Gateway Type)."
S3BucketName1:
default: "S3BucketName1: Type your bucket for creating object"
ECRRepositoryName1:
default: "ECRRepositoryName1: Type your Repository for shipping docker images"
# ------------------------------------------------------------#
# Parameters
# This Can enable templates to input custom values each time you create or update a stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html.
# ------------------------------------------------------------#
Parameters:
SystemName:
Type: String
EnvType:
Type: String
Default: "dev"
AllowedValues:
- dev
- stg
- prd
Tagprefix:
Type: String
Owner:
Type: String
VPCID:
Type: AWS::EC2::VPC::Id
ConstraintDescription: "Select VPC's ID"
VPCCIDR:
Type: String
Default: "10.0.0.0/16"
ConstraintDescription: "This is for deciding Security Group Ingress CIDR for instance in VPC. Type VPC's CIDR such as NN.NN.NN.NN/NN based on RFC 1918."
InterfaceSubnetId1:
Type : AWS::EC2::Subnet::Id
ConstraintDescription: "Select private subnet-1a associated with VPC Endpoints(Interface Type)"
InterfaceSubnetId2:
Type : AWS::EC2::Subnet::Id
ConstraintDescription: "Select private subnet-1c associated with VPC Endpoints(Interface Type)"
RouteTableId1:
Type: String
Default: "rtb-XXXXXXXXXXXXXXXXX"
ConstraintDescription: "Type your RouteTableId for private subnet-1a associated with VPC Endpoints(Gateway Type)."
RouteTableId2:
Type: String
Default: "rtb-XXXXXXXXXXXXXXXXX"
ConstraintDescription: "Type your RouteTableId for private subnet-1c associated with VPC Endpoints(Gateway Type)."
S3BucketName1:
Type: String
ConstraintDescription: "Type your bucket for creating object"
ECRRepositoryName1:
Type: String
ConstraintDescription: "Type your Repository for shipping docker images"
# ------------------------------------------------------------#
# Resources
# This can declare the AWS resources that you want to include in the stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# The building phase is not designated to set up resource based policy.
# So note that we deleted related resources.
# ------------------------------------------------------------#
Resources:
# ------------------------------------------------------------#
# Create IAM Roles for ECS task and ECS task execution.
# ------------------------------------------------------------#
IAMRoleforECSTask1:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-Task-IAM-Role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action:
- sts:AssumeRole
MaxSessionDuration: 3600
Path: /
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-Task-IAM-Role
- Key: Owner
Value: !Ref Owner
IAMRoleforECSTaskExecution1:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-TaskExecution-IAM-Role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action:
- sts:AssumeRole
MaxSessionDuration: 3600
Path: /
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-TaskExecution-IAM-Role
- Key: Owner
Value: !Ref Owner
# ------------------------------------------------------------#
# Create Instance Profiles for IAM Roles
# ------------------------------------------------------------#
InstanceProfileforECSTask1:
Type: 'AWS::IAM::InstanceProfile'
Properties:
InstanceProfileName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-Task-IAM-Role
Path: /
Roles:
- !Ref IAMRoleforECSTask1
DependsOn: IAMRoleforECSTask1
InstanceProfileforECSTaskExecution1:
Type: 'AWS::IAM::InstanceProfile'
Properties:
InstanceProfileName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-TaskExecution-IAM-Role
Path: /
Roles:
- !Ref IAMRoleforECSTaskExecution1
DependsOn: IAMRoleforECSTaskExecution1
# ------------------------------------------------------------#
# Create IAM Policies for IAM Roles
# ------------------------------------------------------------#
IAMPolicyforECSTaskRole1:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
Description: Policy for ECS Task Role
Path: /
ManagedPolicyName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-Task-IAM-Policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Sid: WidePolicyforBucket
Action:
- s3:ListBucket
- s3:Get*
- s3:PutObject
- s3:PutObjectAcl
Resource:
- !Sub 'arn:aws:s3:::${S3BucketName1}'
- !Sub 'arn:aws:s3:::${S3BucketName1}/*'
Roles:
- !Ref IAMRoleforECSTask1
IAMPolicyforECSTaskExecutionRole1:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
Description: Policy for ECS Task execution Role
Path: /
ManagedPolicyName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-TaskExecution-IAM-Policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Sid: ECRPolicy
Action:
- ecr:BatchCheckLayerAvailability
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
Resource: !Sub 'arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/${ECRRepositoryName1}'
- Effect: Allow
Sid: LoggroupPolicy
Action:
- logs:CreateLogStream
Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:*'
- Effect: Allow
Sid: LogstreamPolicy
Action:
- logs:PutLogEvents
Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:*:log-stream:*'
- Effect: Allow
Action: ecr:GetAuthorizationToken
Resource: '*'
- Effect: Allow
Action: s3:GetObject
Resource: !Sub 'arn:aws:s3:::prod-${AWS::Region}-starport-layer-bucket/*'
- Effect: Allow
Sid: ReadBucketOnly
Action:
- s3:ListBucket
- s3:Get*
Resource:
- !Sub 'arn:aws:s3:::${S3BucketName1}'
- !Sub 'arn:aws:s3:::${S3BucketName1}/*'
Roles:
- !Ref IAMRoleforECSTaskExecution1
# ------------------------------------------------------------#
# Create Security Group for VPC EndPoint(CloudWatch Logs)
# ------------------------------------------------------------#
SecurityGroupEndpointsLogs:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-ForEndpoint-logs
GroupDescription: Security Group for Logs VPC Endpoint.
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: !Ref VPCCIDR
VpcId: !Ref VPCID
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-ForEndpoint-logs
- Key: Owner
Value: !Ref Owner
# ------------------------------------------------------------#
# Create Security Group for VPC End Point(ECR)
# The building phase is not designated to set up resource based policy.
# So note that we deleted related resources.
# ------------------------------------------------------------#
SecurityGroupEndpointsEcrdkr:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-ForEndpoint-Ecrdkr
GroupDescription: Security Group for ECR VPC Endpoint.
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: !Ref VPCCIDR
VpcId: !Ref VPCID
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-ForEndpoint-Ecrdkr
- Key: Owner
Value: !Ref Owner
SecurityGroupEndpointsEcrapi:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-ForEndpoint-Ecrapi
GroupDescription: Security Group for ECR VPC Endpoint.
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: !Ref VPCCIDR
VpcId: !Ref VPCID
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-ForEndpoint-Ecrapi
- Key: Owner
Value: !Ref Owner
# ------------------------------------------------------------#
# Create CloudWatch Logs End Point
# VPCEndpoints is unsupported to use property Tags.
# The building phase is not designated to set up resource based policy.
# So note that we deleted related resources.
# ------------------------------------------------------------#
LogsEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Sub com.amazonaws.${AWS::Region}.logs
SubnetIds:
- !Ref InterfaceSubnetId1
- !Ref InterfaceSubnetId2
VpcId: !Ref VPCID
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref SecurityGroupEndpointsLogs
PrivateDnsEnabled: true
DependsOn:
- SecurityGroupEndpointsLogs
- IAMPolicyforECSTaskExecutionRole1
- InstanceProfileforECSTaskExecution1
# ------------------------------------------------------------#
# Create ECR End Point
# Amazon ECS tasks hosted on Fargate using platform version 1.4.0 or later require both the com.amazonaws.region.ecr.dkr
# and com.amazonaws.region.ecr.api Amazon ECR VPC endpoints as well as the Amazon S3 gateway endpoint to take advantage of this feature.
# For more information, see https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html
# VPCEndpoints is unsupported to use property Tags.
# The building phase is not designated to set up resource based policy.
# So note that we deleted related resources.
# ------------------------------------------------------------#
EcrdkrEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Sub com.amazonaws.${AWS::Region}.ecr.dkr
SubnetIds:
- !Ref InterfaceSubnetId1
- !Ref InterfaceSubnetId2
VpcId: !Ref VPCID
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref SecurityGroupEndpointsEcrdkr
PrivateDnsEnabled: true
DependsOn:
- SecurityGroupEndpointsEcrdkr
- IAMPolicyforECSTaskExecutionRole1
EcrapiEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Sub com.amazonaws.${AWS::Region}.ecr.api
SubnetIds:
- !Ref InterfaceSubnetId1
- !Ref InterfaceSubnetId2
VpcId: !Ref VPCID
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref SecurityGroupEndpointsEcrapi
PrivateDnsEnabled: true
DependsOn:
- SecurityGroupEndpointsEcrapi
- IAMPolicyforECSTaskExecutionRole1
# ------------------------------------------------------------#
# Create S3 End Point(Gateway)
# VPCEndpoints is unsupported to use property Tags.
# The building phase is not designated to set up resource based policy.
# So note that we deleted related resources.
# ------------------------------------------------------------#
S3GatewayEndpoint:
Type: 'AWS::EC2::VPCEndpoint'
Properties:
RouteTableIds:
- !Ref RouteTableId1
- !Ref RouteTableId2
ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
VpcId: !Ref VPCID
VpcEndpointType: Gateway
DependsOn: IAMPolicyforECSTaskRole1
# ------------------------------------------------------------#
# Outputs
# This can output each value specified as output section.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Outputs:
# ------------------------------------------------------------#
# Output Security Groups
# ------------------------------------------------------------#
SecurityGroupEndpointsLogs:
Description: SecurityGroupEndpointsLogs
Value: !Ref SecurityGroupEndpointsLogs
SecurityGroupEndpointsEcrdkr:
Description: SecurityGroupEndpointsEcrdkr
Value: !Ref SecurityGroupEndpointsEcrdkr
SecurityGroupEndpointsEcrapi:
Description: SecurityGroupEndpointsEcrapi
Value: !Ref SecurityGroupEndpointsEcrapi
# ------------------------------------------------------------#
# Output IAM Resources
# ------------------------------------------------------------#
IAMRoleforECSTask1:
Description: IAMRoleforECSTask1
Value: !Ref IAMRoleforECSTask1
IAMRoleforECSTaskExecution1:
Description: IAMRoleforECSTaskExecution1
Value: !Ref IAMRoleforECSTaskExecution1
InstanceProfileforECSTask1:
Description: InstanceProfileforECSTask1
Value: !Ref InstanceProfileforECSTask1
InstanceProfileforECSTaskExecution1:
Description: InstanceProfileforECSTaskExecution1
Value: !Ref InstanceProfileforECSTaskExecution1
IAMPolicyforECSTaskRole1:
Description: IAMPolicyforECSTaskRole1
Value: !Ref IAMPolicyforECSTaskRole1
IAMPolicyforECSTaskExecutionRole1:
Description: IAMPolicyforECSTaskExecutionRole1
Value: !Ref IAMPolicyforECSTaskExecutionRole1
# ------------------------------------------------------------#
# Output VPC Endpoints using Interface Type
# ------------------------------------------------------------#
LogsEndpoint:
Description: LogsEndpoint
Value: !Ref LogsEndpoint
EcrdkrEndpoint:
Description: EcrdkrEndpoint
Value: !Ref EcrdkrEndpoint
EcrapiEndpoint:
Description: EcrapiEndpoint
Value: !Ref EcrapiEndpoint
# ------------------------------------------------------------#
# Output VPC Endpoints using Gateway Type
# ------------------------------------------------------------#
S3GatewayEndpoint:
Description: S3GatewayEndpoint
Value: !Ref S3GatewayEndpoint
4.5 ECSおよび関連リソースを作成
- ECSクラスター、タスク定義を作成する
- また、タスク実行時にログ出力先としてCloudWatch Logsのロググループもここで作成する
- ECSのコンテナ設定でイメージ取得先を設定しているECRに格納されているイメージと同一になる様に留意すること
- ECSのストレージとして、EFSを作成している
以下の情報を基にスタックを作成する。
パラメータ値:
項目 | 備考 |
---|---|
SystemName |
プロジェクト名や利用目的等を入力する |
EnvType |
デプロイする環境を選択する 検証、ステージング、本番の3点 |
Tagprefix |
任意で入力するPrefix値を指定する |
Owner |
作業者、所有者、コスト管理用に入力する |
ECSTaskCPUUnit |
ECSタスクを起動するためのCPUユニット値を選択する (任意の値) |
ECSTaskMemory |
ECSタスクを起動するためのメモリ値を選択 (任意の値) |
VPCID |
作成済みのVPCのID |
VPCCIDR |
作成済みのVPCのCIDR |
PrivateSubnet1 |
作成済みVPCのプライベートサブネット(AZは1a) |
PrivateSubnet2 |
作成済みVPCのプライベートサブネット(AZは1c) |
ECRRepositoryName1 |
作成済みのECRリポジトリ名 |
TaskRoleArn |
作成したタスク用IAMロールのARN |
ExecutionRoleArn |
作成したタスク実行用IAMロールのARN |
4.5.1 テンプレート情報
AWSTemplateFormatVersion: "2010-09-09"
Description: Create ECS and related resources such as EFS, CloudWatch Logs
# ------------------------------------------------------------#
# Caution:
# This template is for deploying resources in Tokyo region(ap-northeast-1).
# ------------------------------------------------------------#
# Metadata:
# This can privide details about the template.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html.
# As Metadata Keys, AWS::CloudFormation::Interface can Defines the grouping and ordering of input parameters
# when they are displayed in the AWS CloudFormation console.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-interface.html.
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
-
Parameters:
- SystemName
- EnvType
- Tagprefix
- Owner
- ECSTaskCPUUnit
- ECSTaskMemory
- VPCID
- VPCCIDR
- PrivateSubnet1
- PrivateSubnet2
- ECRRepositoryName1
- TaskRoleArn
- ExecutionRoleArn
ParameterLabels:
SystemName:
default: "SystemName: Type the Systemname"
EnvType:
default: "EnvType: Select the environment in which you deploy resources"
Tagprefix:
default: "Tagprefix: Type the Tagprefix which is logical unit name about this stack(e.g. Webserver,Monitoring,Logging)"
Owner:
default: "Owner: Type who owns these resources (e.g. project name or worker, whether this purpose is just verification or not)"
ECSTaskCPUUnit:
default: "ECSTaskCPUUnit: Select CPUUnit you use for ECSTask"
ECSTaskMemory:
default: "ECSTaskMemory: Select Memory you use for ECSTask"
VPCID:
default: "VPCID: Select the VPC ID"
VPCCIDR:
default: "VPCCIDR: This is for deciding Security Group Ingress CIDR for instance in VPC. Type VPC's CIDR such as NN.NN.NN.NN/NN based on RFC 1918."
PrivateSubnet1:
default: "PrivateSubnet1: Select your subnet's CIDR in AZ-A such as NN.NN.NN.NN/NN based on RFC 1918"
PrivateSubnet2:
default: "PrivateSubnet2: Select your subnet's CIDR in AZ-C such as NN.NN.NN.NN/NN based on RFC 1918"
ECRRepositoryName1:
default: "ECRRepositoryName1: Type your Repository for shipping docker images"
TaskRoleArn:
default: "TaskRoleArn: Type ARN of IAM Role for task assumed by the containers running in the task"
ExecutionRoleArn:
default: "ExecutionRoleArn: Type ARN of IAM Role for task executed by Fargate agents to make AWS API calls on your behalf"
# ------------------------------------------------------------#
# Parameters
# This Can enable templates to input custom values each time you create or update a stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html.
# ------------------------------------------------------------#
Parameters:
SystemName:
Type: String
EnvType:
Type: String
Default: "dev"
AllowedValues:
- dev
- stg
- prd
Tagprefix:
Type: String
Owner:
Type: String
ECSTaskCPUUnit:
AllowedValues: [ 256, 512, 1024, 2048, 4096 ]
Type: String
Default: "256"
ECSTaskMemory:
AllowedValues: [ 256, 512, 1024, 2048, 4096 ]
Type: String
Default: "512"
VPCID:
Type: AWS::EC2::VPC::Id
ConstraintDescription: "Select the VPC ID"
VPCCIDR:
Type: String
Default: "10.0.0.0/16"
ConstraintDescription: "This is for deciding Security Group Ingress CIDR for instance in VPC. So please type VPC's CIDR such as NN.NN.NN.NN/NN based on RFC 1918."
PrivateSubnet1:
Type: AWS::EC2::Subnet::Id
ConstraintDescription: "Select your subnet's CIDR in AZ-A such as NN.NN.NN.NN/NN based on RFC 1918"
PrivateSubnet2:
Type: AWS::EC2::Subnet::Id
ConstraintDescription: "Select your subnet's CIDR in AZ-C such as NN.NN.NN.NN/NN based on RFC 1918"
ECRRepositoryName1:
Type: String
ConstraintDescription: "Type your Repository for shipping docker images"
TaskRoleArn:
Type: String
ConstraintDescription: "Type ARN of IAM Role for task assumed by the containers running in the task"
ExecutionRoleArn:
Type: String
ConstraintDescription: "Type ARN of IAM Role for task executed by Fargate agents to make AWS API calls on your behalf"
# ------------------------------------------------------------#
# Resources
# This can declare the AWS resources that you want to include in the stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Resources:
#---------------------------------
# Create Security Group for Mount target in EFS.
#---------------------------------
EFSSecurityGroup1:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-ForEFS
GroupDescription: Security Group for Mount target in EFS
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 2049
ToPort: 2049
CidrIp: !Ref VPCCIDR
VpcId: !Ref VPCID
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-ForEFS
- Key: Owner
Value: !Ref Owner
#---------------------------------
# Create EFS File system
# BypassPolicyLockoutSafetyCheck is not used because this EFS does not set up File system Policy.
# For more information about BypassPolicyLockoutSafetyCheck, see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-efs-filesystem.html#cfn-efs-filesystem-bypasspolicylockoutsafetycheck
# LifecyclePolicies is not used because this EFS does not use itself for infrequent access and basically uses EFS Standard class.
#---------------------------------
EFSFileSystem1:
Type: AWS::EFS::FileSystem
Properties:
BackupPolicy:
Status: DISABLED
Encrypted: true
FileSystemTags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-EFS-FileSystem
- Key: Owner
Value: !Ref Owner
PerformanceMode: generalPurpose
ThroughputMode: bursting
#---------------------------------
# Create EFS Mount Target
#---------------------------------
EFSMountTarget1:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref EFSFileSystem1
SecurityGroups:
- !Ref EFSSecurityGroup1
SubnetId: !Ref PrivateSubnet1
DependsOn:
- EFSFileSystem1
EFSMountTarget2:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref EFSFileSystem1
SecurityGroups:
- !Ref EFSSecurityGroup1
SubnetId: !Ref PrivateSubnet2
DependsOn:
- EFSFileSystem1
# ------------------------------------------------------------#
# Create ECS LogGroup
# ------------------------------------------------------------#
ECSLogGroup1:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/ecs/logs/${SystemName}-${EnvType}-${Tagprefix}-ECS-Cluster"
RetentionInDays: 30
# ------------------------------------------------------------#
# Create ECS Cluster
# ------------------------------------------------------------#
ECSCluster1:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-Cluster
ClusterSettings:
- Name: containerInsights
Value: enabled
CapacityProviders:
- FARGATE
DefaultCapacityProviderStrategy:
- CapacityProvider: FARGATE
Base: 1
Weight: 1
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-Cluster
- Key: Owner
Value: !Ref Owner
# ------------------------------------------------------------#
# ECS TaskDefinition
# ------------------------------------------------------------#
ECSTaskDefinition1:
Type: AWS::ECS::TaskDefinition
Properties:
Cpu: !Ref ECSTaskCPUUnit
ExecutionRoleArn: !Ref ExecutionRoleArn
TaskRoleArn: !Ref TaskRoleArn
Family: !Sub ${SystemName}-${EnvType}-${Tagprefix}-TaskFamily
Memory: !Ref ECSTaskMemory
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
RuntimePlatform:
CpuArchitecture: X86_64
OperatingSystemFamily: LINUX
Volumes:
- Name: efs-mount-target-vol
EFSVolumeConfiguration:
FileSystemId: !Ref EFSFileSystem1
RootDirectory: /
TransitEncryption: ENABLED
AuthorizationConfig:
IAM: DISABLED
ContainerDefinitions:
- Name: !Sub ${SystemName}-${EnvType}-${Tagprefix}-Container
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${ECRRepositoryName1}:latest
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref ECSLogGroup1
awslogs-region: !Ref "AWS::Region"
awslogs-stream-prefix: !Sub ${SystemName}-${EnvType}-${Tagprefix}-container
PortMappings:
- Protocol: tcp
ContainerPort: 443
MountPoints:
- ContainerPath: /mounttarget
ReadOnly: False
SourceVolume: efs-mount-target-vol
Tags:
- Key: Owner
Value: !Ref Owner
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-ECS-TaskDefinition
DependsOn:
- EFSMountTarget1
- EFSMountTarget2
# ------------------------------------------------------------#
# Outputs
# This can output each value specified as output section.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Outputs:
ECSCluster1:
Description: ECSCluster1
Value: !Ref ECSCluster1
ECSTaskDefinition1:
Description: ECSTaskDefinition1
Value: !Ref ECSTaskDefinition1
ECSLogGroup1:
Description: ECSLogGroup1
Value: !Ref ECSLogGroup1
EFSSecurityGroup1:
Description: EFSSecurityGroup1
Value: !Ref EFSSecurityGroup1
EFSFileSystem1:
Description: EFSFileSystem1
Value: !Ref EFSFileSystem1
EFSMountTarget1:
Description: EFSMountTarget1
Value: !Ref EFSMountTarget1
EFSMountTarget2:
Description: EFSMountTarget2
Value: !Ref EFSMountTarget2
4.6 EventBridgeルール、関連リソース作成
- ECSタスクにイベントを通知するEventBridgeのルールを作成する
- またECSタスクにアクセス出来る様にするIAMロールもここで作成する
- Fargateのバージョンをこのテンプレートで指定している
- プラットフォームのバージョンは1.4である、必要に応じて適宜変更する
以下の情報を基にスタックを作成する
パラメータ値:
項目 | 備考 |
---|---|
SystemName |
プロジェクト名や利用目的等を入力する |
EnvType |
デプロイする環境を選択する 検証、ステージング、本番の3点 |
Tagprefix |
任意で入力するPrefix値を指定する |
Owner |
作業者、所有者、コスト管理用に入力する |
VPCID |
作成済みのVPCのID |
PrivateSubnet1 |
作成済みVPCのプライベートサブネット(AZは1a) |
PrivateSubnet2 |
作成済みVPCのプライベートサブネット(AZは1c) |
S3BucketName1 |
作成したS3バケット名 |
PrefixName1 |
イベント駆動する格納先のパス 例:バケット直下のeventディレクトリにtest.txtを格納する場合は event/test.txt
|
ECSClusterName1 |
作成済みECSのクラスター名 |
TaskDefinitionName1 |
作成済みECSのタスク定義名 |
4.6.1 テンプレート情報
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy an EventBridge Rule.
# ------------------------------------------------------------#
# Caution:
# This template is for deploying resources in Tokyo region(ap-northeast-1).
# ------------------------------------------------------------#
# Metadata:
# This can privide details about the template.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html.
# As Metadata Keys, AWS::CloudFormation::Interface can Defines the grouping and ordering of input parameters
# when they are displayed in the AWS CloudFormation console.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-interface.html.
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
-
Parameters:
- SystemName
- EnvType
- Tagprefix
- Owner
- VPCID
- PrivateSubnet1
- PrivateSubnet2
- S3BucketName1
- PrefixName1
- ECSClusterName1
- TaskDefinitionName1
ParameterLabels:
SystemName:
default: "SystemName: Type the Systemname"
EnvType:
default: "EnvType: Select the environment in which you deploy resources"
Tagprefix:
default: "Tagprefix: Type the Tagprefix which is logical unit name about this stack(e.g. Webserver,Monitoring,Logging)"
Owner:
default: "Owner: Type who owns these resources (e.g. project name or worker, whether this purpose is just verification or not)"
VPCID:
default: "VPCID: Select the VPC ID"
PrivateSubnet1:
default: "PrivateSubnet1: Select your subnet's CIDR in AZ-A such as NN.NN.NN.NN/NN based on RFC 1918"
PrivateSubnet2:
default: "PrivateSubnet2: Select your subnet's CIDR in AZ-C such as NN.NN.NN.NN/NN based on RFC 1918"
S3BucketName1:
default: "S3BucketName1: Type your bucket name triggered to EventBridge(must not contain uppercase characters)"
PrefixName1:
default: "PrefixName1: Type prefix name for above bucket(Do not contain uppercase characters) such as XXX/XXX/XXX.csv"
ECSClusterName1:
default: "ECSClusterName1: Type name of ECSCluster for target"
TaskDefinitionName1:
default: "TaskDefinitionName1: Type name of task definition for target"
# ------------------------------------------------------------#
# Parameters
# This Can enable templates to input custom values each time you create or update a stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html.
# ------------------------------------------------------------#
Parameters:
SystemName:
Type: String
EnvType:
Type: String
Default: "dev"
AllowedValues:
- dev
- stg
- prd
Tagprefix:
Type: String
Owner:
Type: String
VPCID:
Type: AWS::EC2::VPC::Id
ConstraintDescription: "Select the VPC ID"
PrivateSubnet1:
Type: AWS::EC2::Subnet::Id
ConstraintDescription: "Select your subnet's CIDR in AZ-A such as NN.NN.NN.NN/NN based on RFC 1918"
PrivateSubnet2:
Type: AWS::EC2::Subnet::Id
ConstraintDescription: "Select your subnet's CIDR in AZ-C such as NN.NN.NN.NN/NN based on RFC 1918"
S3BucketName1:
Type: String
ConstraintDescription: "Type your bucket name triggered to EventBridge(must not contain uppercase characters)"
PrefixName1:
Type: String
ConstraintDescription: "Type prefix name for above bucket(Do not contain uppercase characters) such as XXX/XXX/XXX.csv"
ECSClusterName1:
Type: String
Default: "XX-XXX-XX-ECS-Cluster"
ConstraintDescription: "Type name of ECSClusterName for Target"
TaskDefinitionName1:
Type: String
Default: "XX-XXX-XX-TaskFamily"
ConstraintDescription: "Type name of task definition for Target "
Resources:
# ------------------------------------------------------------#
# Create Security Gruop Task execution
# ------------------------------------------------------------#
SecurityGroupForTaskexecution1:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-Taskexecution1
GroupDescription: Security Group for Task execution.
VpcId: !Ref VPCID
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-Taskexecution1
- Key: Owner
Value: !Ref Owner
# ------------------------------------------------------------#
# Create IAM Role for EventBridge Rule
# ------------------------------------------------------------#
EventBridgeRuleRole1:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-EventBridge-Role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Principal:
Service:
- "events.amazonaws.com"
Action:
- "sts:AssumeRole"
Path: "/"
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-EventBridge-Role
- Key: Owner
Value: !Ref Owner
# ------------------------------------------------------------#
# Create IAM Policy for EventBridge Rule
# ------------------------------------------------------------#
EventBridgeRulePolicy1:
Type: "AWS::IAM::ManagedPolicy"
Properties:
Description: Policy for EventBridge Rule
Path: /
ManagedPolicyName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-EventBridge-Policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "ecs:RunTask"
Resource:
- !Sub arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:task-definition/${TaskDefinitionName1}:*
- !Sub arn:aws:ecs:*:${AWS::AccountId}:task-definition/${TaskDefinitionName1}
Condition:
ArnLike:
ecs:cluster: !Sub arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${ECSClusterName1}
- Effect: "Allow"
Action:
- "iam:PassRole"
Resource:
- "*"
Condition:
StringLike:
iam:PassedToService: "ecs-tasks.amazonaws.com"
Roles:
- Ref: EventBridgeRuleRole1
# ------------------------------------------------------------#
# Create EventBridge Rule triggered by S3 bucket
# ------------------------------------------------------------#
EventBridgeRule1:
Type: 'AWS::Events::Rule'
Properties:
Name: !Sub ${SystemName}-${EnvType}-${Tagprefix}-EventBridge-Rule-S3-Object
Description: "Events Rule triggered by S3 Object event to ECS task execution"
EventBusName: "default"
EventPattern:
source:
- aws.s3
detail-type:
- Object Created
detail:
bucket:
name:
- Ref: S3BucketName1
object:
key:
- prefix: !Ref PrefixName1
Targets:
- Arn: !Sub arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${ECSClusterName1}
Id: RuletoTask1
RoleArn: !GetAtt EventBridgeRuleRole1.Arn
EcsParameters:
EnableECSManagedTags: true
EnableExecuteCommand: false
LaunchType: FARGATE
PlatformVersion: 1.4.0
NetworkConfiguration:
AwsVpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref SecurityGroupForTaskexecution1
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
PropagateTags: TASK_DEFINITION
TaskCount: 1
TaskDefinitionArn: !Sub arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:task-definition/${TaskDefinitionName1}
# ------------------------------------------------------------#
# Outputs
# This can output each value specified as output section.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Outputs:
SecurityGroupForTaskexecution1:
Description: SecurityGroupForTaskexecution1
Value: !Ref SecurityGroupForTaskexecution1
EventBridgeRuleRole1:
Description: EventBridgeRuleRole1
Value: !Ref EventBridgeRuleRole1
EventBridgeRulePolicy1:
Description: EventBridgeRulePolicy1
Value: !Ref EventBridgeRulePolicy1
EventBridgeRule1:
Description: EventBridgeRule1
Value: !Ref EventBridgeRule1
5. まとめ
一式の環境を構築する為のテンプレートをご紹介しました。
環境構築には比較的時間を要しますし、役に立ちそうであれば、是非ともご利用ください。
また、これらのリソースを用いてECSタスクを起動する記事は別途書こうと思います。
この記事が誰かの役に立てば嬉しいです!Mitsuoでした!
Discussion
同じようなことがやりたくて凄く参考になりました。
何より見やすかったです!