CloudFormation で Fargate の環境を作ってみる

表題の件を書き残しておこうと思います。
スペックは、後々インプットパラメータで指定できるようにしたいところです。

参考

構成図

下記構成図です。

コード

下記コードです。

AWSTemplateFormatVersion: "2010-09-09"
Description: Create ECS Task Test

Parameters:
  ImageUri:
    Type: String
    Default: ""

Resources:
  ########################################################
  ### VPC
  ########################################################
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: "true"
      EnableDnsHostnames: "true"
      InstanceTenancy: "default"
      Tags:
        - Key: Name
          Value: "hoge-vpc"

  ########################################################
  ### Subnet
  ########################################################
  PublicSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: 10.0.0.0/24
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: "hoge-public-subnet-a"
  PublicSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: "ap-northeast-1c"
      CidrBlock: 10.0.1.0/24
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: "hoge-public-subnet-b"

  ########################################################
  ### Route Table
  ########################################################
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: "hoge-public-routetable"
  # way to InternetGateway
  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  # attach to SubnetA
  PublicSubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetA
      RouteTableId: !Ref PublicRouteTable
  # attach to SubnetB
  PublicSubnetBRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetB
      RouteTableId: !Ref PublicRouteTable

  ########################################################
  ### InternetGateway
  ########################################################
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: "hoge-igw"
  Attachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  ########################################################
  ### Target Group
  ########################################################
  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      VpcId: !Ref VPC
      Name: "hoge-target-group"
      Protocol: HTTP
      Port: 80
      TargetType: ip

  ########################################################
  ### ALB Security Group
  ########################################################
  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: "hoge-alb-sg"
      GroupDescription: "Allow HTTP access"
      VpcId: !Ref VPC
      # Rule
      SecurityGroupIngress:
        # http
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

  ########################################################
  ### ALB
  ########################################################
  InternetALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: "hoge-alb"
      Scheme: "internet-facing"
      LoadBalancerAttributes:
        - Key: "deletion_protection.enabled"
          Value: false
        - Key: "idle_timeout.timeout_seconds"
          Value: 60
      SecurityGroups:
        - !Ref ALBSecurityGroup
      Subnets:
        - !Ref PublicSubnetA
        - !Ref PublicSubnetB

  ########################################################
  ### ALB Listener
  ########################################################
  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - TargetGroupArn: !Ref TargetGroup
          Type: forward
      LoadBalancerArn: !Ref InternetALB
      Port: 80
      Protocol: HTTP

  ########################################################
  ### ECS Task Role
  ########################################################
  EcsTaskExecRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: "hoge-ecs-task-exec-role-policy"
      Path: /
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

  ########################################################
  ### ECS TaskDefinition
  ########################################################
  EcsTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Cpu: 256
      ExecutionRoleArn: !Ref EcsTaskExecRole
      Family: "hoge-ecs-task"
      Memory: 512
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ### ContainerDefinitions
      ContainerDefinitions:
        - Name: "hoge-ecs-container"
          Image: !Ref ImageUri
          MemoryReservation: 128
          PortMappings:
            - HostPort: 80
              Protocol: tcp
              ContainerPort: 80

  ########################################################
  ### ECS Service
  ########################################################
  EcsServiceA:
    Type: AWS::ECS::Service
    DependsOn: ALBListener
    Properties:
      Cluster: !Ref EcsCluster
      DesiredCount: 1
      LaunchType: FARGATE
      LoadBalancers:
        - TargetGroupArn: !Ref TargetGroup
          ContainerPort: 80
          ContainerName: "hoge-ecs-container"
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - !Ref ALBSecurityGroup
          Subnets:
            - !Ref PublicSubnetA
      ServiceName: "hoge-ecs-service-a"
      TaskDefinition: !Ref EcsTaskDefinition

  EcsServiceB:
    Type: AWS::ECS::Service
    DependsOn: ALBListener
    Properties:
      Cluster: !Ref EcsCluster
      DesiredCount: 1
      LaunchType: FARGATE
      LoadBalancers:
        - TargetGroupArn: !Ref TargetGroup
          ContainerPort: 80
          ContainerName: "hoge-ecs-container"
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - !Ref ALBSecurityGroup
          Subnets:
            - !Ref PublicSubnetB
      ServiceName: "hoge-ecs-service-b"
      TaskDefinition: !Ref EcsTaskDefinition

  ########################################################
  ### ECS Cluster
  ########################################################
  EcsCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: "hoge-ecs-cluster"

Outputs:
  EcsCluster:
    Value: !Ref EcsCluster
    Export:
      Name: EcsCluster

  TargetGroup:
    Value: !Ref TargetGroup
    Export:
      Name: TargetGroup

  ALBListener:
    Value: !Ref ALBListener
    Export:
      Name: ALBListener