kawabatas技術ブログ

試してみたことを書いていきます

ECS Fargate + NLB を CloudFormation で構築する

概要

ECS Fargate + NLB を CloudFormation でテンプレート化した。

VPC、Subnet、ECRリポジトリは事前に作成済みとし、

ECSクラスター/サービス/タスク定義、NLB、ターゲットグループ、セキュリティグループを CloudFormation で作成する。

参考

AWS CloudFormation の公式ドキュメント

(2017年12月時点) 私的 CloudFormation ベストプラクティスも参考にさせていただいた。

コード

AWSTemplateFormatVersion: '2010-09-09'
Description: Create ECS Resources

Parameters:
  NamePrefix:
    Type: String
    Default: <リソース名のプレフィックス>
  Port:
    Type: Number
    Default: 80
  VpcId:
    Type: AWS::EC2::VPC::Id
    Default: <VPCのID>
  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Default: <SubnetのID>,<SubnetのID>,<SubnetのID>
  ECRRepositoryName:
    Type: String
    Default: <ECRリポジトリ名>

# VPC,Subnet,ECRリポジトリは事前に作成済みとする
Resources:
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Sub ${NamePrefix}-Cluster
  ECSTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      ContainerDefinitions:
        - Name: !Sub ${NamePrefix}-Container
          Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${ECRRepositoryName}:latest
          PortMappings:
            - ContainerPort: !Ref Port
              HostPort: !Ref Port
              Protocol: tcp
          # コンテナが失敗した場合はタスクが停止する設定
          Essential: true
      Cpu: 256
      ExecutionRoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole
      Family: !Sub ${NamePrefix}-Task
      Memory: 512
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
  ECSService:
    Type: AWS::ECS::Service
    DependsOn:
      - ECSCluster
      - ECSTaskDefinition
      - SecurityGroup
      - TargetGroup
      - LoadBalancerListener
    Properties:
      Cluster: !Ref ECSCluster
      DesiredCount: 1
      LaunchType: FARGATE
      LoadBalancers:
        - ContainerName: !Sub ${NamePrefix}-Container
          ContainerPort: !Ref Port
          TargetGroupArn: !Ref TargetGroup
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - !Ref SecurityGroup
          Subnets: !Ref SubnetIds
      ServiceName: !Sub ${NamePrefix}-Service
      TaskDefinition: !Ref ECSTaskDefinition
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub ${NamePrefix}-SecurityGroup
      GroupDescription: !Sub ${NamePrefix}-SecurityGroup
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: !Ref Port
          ToPort: !Ref Port
          CidrIp: 0.0.0.0/0
      VpcId: !Ref VpcId
  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${NamePrefix}-NLB
      Subnets: !Ref SubnetIds
      Scheme: internet-facing
      Type: network
  LoadBalancerListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    DependsOn:
      - LoadBalancer
      - TargetGroup
    Properties:
      LoadBalancerArn: !Ref LoadBalancer
      Port: !Ref Port
      Protocol: TCP
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref TargetGroup
  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${NamePrefix}-targetgroup
      VpcId: !Ref VpcId
      Port: !Ref Port
      Protocol: TCP
      TargetType: ip