LoginSignup
6
3

More than 3 years have passed since last update.

ECS(Fargate)のバッチをCloudFormationで作成する

Last updated at Posted at 2019-10-11

お試しで作ったものの備忘メモ

  • 以下のリソースが作成されます
    • ECS
      • クラスタ
      • タスク定義
        • Fargateタイプ
        • ネットワークモードはawsvpc
      • タスクスケジュール(CloudWatch Events)
        • 毎日12時に動く
    • ECR
      • 直近2イメージのみ保持
  • 以下が前提になります
    • プライベートサブネット、セキュリティグループが作成済
    • ecsTaskExecutionRoleが作成済
    • SSMのパラメーターストアにてyour_secrets_valueという名前のシークレットが作成済
      • 必要なければSecretsを消せばOK
  • 本日時点で、AWS::Events::Rule EcsParametersの日本語記事を読むとNetworkConfigurationなどの指定ができないように思えますが、英語版には普通に書いてある...ということを伝えたくて書きました
    • フィードバックは送り済みなのでそのうち直るかも
sample.yml
AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  ResourceName:
    Type: String
    Description: Resource Name
  RepositoryName:
    Type: String
    Description: Repository Name
  ImageTagName:
    Type: String
    Description: Image Tag Name
  TaskDefinitionCpu:
    Type: Number
    Description: TaskDefinition Cpu
  TaskDefinitionMemory:
    Type: Number
    Description: TaskDefinition Memory
  TaskExecutionSecurityGroups:
    Type: List<AWS::EC2::SecurityGroup::Id>
    Description: Service SecurityGroups
  TaskExecutionSubnets:
    Type: List<AWS::EC2::Subnet::Id>
    Description: Service Subnets

Resources:
  Cluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName:
        Ref: ResourceName

  Repository:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryName:
        Ref: RepositoryName
      LifecyclePolicy:
        # https://dev.classmethod.jp/cloud/aws/cfn-for-ecr-lifecyclepolicy/
        LifecyclePolicyText: |
          {
            "rules" : [
              {
                "rulePriority" : 1,
                "description" : "Delete more than 2 images",
                "selection" : {"countType" : "imageCountMoreThan", "countNumber" : 2, "tagStatus" : "any"},
                "action" : {"type" : "expire"}
              }
            ]
          }

  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family:
        Ref: ResourceName
      Cpu:
        Ref: TaskDefinitionCpu
      Memory:
        Ref: TaskDefinitionMemory
      NetworkMode: awsvpc
      ExecutionRoleArn:
        Fn::Sub: arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole
      RequiresCompatibilities:
        - FARGATE
      ContainerDefinitions:
        - Name:
            Ref: ResourceName
          Image:
            Fn::Sub: ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${RepositoryName}:${ImageTagName}
          Secrets:
            # https://dev.classmethod.jp/cloud/aws/ecs-secrets/
            - Name: YOUR_SECRETS_VALUE
              ValueFrom: your_secrets_value
          LogConfiguration:
            LogDriver: awslogs
            Options:
              "awslogs-region":
                Ref: AWS::Region
              "awslogs-stream-prefix": ecs
              "awslogs-group":
                Fn::Sub: /aws/ecs/${ResourceName}

  TaskSchedule:
    Type: AWS::Events::Rule
    Properties:
      Name: sample_task
      State: ENABLED
      ScheduleExpression: cron(0 3 * * ? *)
      Targets:
        - Id: sample_task
          Arn:
            Fn::GetAtt: [Cluster, Arn]
          RoleArn:
            Fn::Sub: arn:aws:iam::${AWS::AccountId}:role/ecsEventsRole
          EcsParameters:
            # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-events-rule-ecsparameters.html
            TaskDefinitionArn:
              Ref: TaskDefinition
            LaunchType: FARGATE
            PlatformVersion: LATEST
            NetworkConfiguration:
              AwsVpcConfiguration:
                AssignPublicIp: DISABLED
                Subnets:
                  Ref: TaskExecutionSubnets
                SecurityGroups:
                  Ref: TaskExecutionSecurityGroups
          Input:
            # コマンドは任意に設定してください!
            Fn::Sub: |
              {
                "containerOverrides" : [
                  {
                    "name" : "${ResourceName}",
                    "command" : ["python3", "-m", "sample_task"]
                  }
                ]
              }

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName:
        Fn::Sub: /aws/ecs/${ResourceName}
      RetentionInDays: 30

以下のような設定ファイルを定義して

parameters.ini
ResourceName=sample-resource
RepositoryName=sample-repository
ImageTagName=smpl
TaskDefinitionCpu=256
TaskDefinitionMemory=512
TaskExecutionSecurityGroups=sg-xxxx
TaskExecutionSubnets=subnet-yyyy,subnet-zzzz

以下のような感じで実行すると楽

ターミナル
# 作成
$ aws cloudformation deploy \
  --stack-name sample-stack \
  --template-file sample.yml \
  --no-fail-on-empty-changeset \
  --parameter-overrides $(cat parameters.ini | tr '\n' ' ')

# オマケ
# DockerイメージをビルドしてECRにpush(99999999はアカウントID)
$ $(aws ecr get-login --no-include-email)
$ docker build -t 99999999.dkr.ecr.ap-northeast-1.amazonaws.com/sample-repository:smpl .
$ docker push 99999999.dkr.ecr.ap-northeast-1.amazonaws.com/sample-repository:smpl

結構面倒でしたが、実際に定義から環境ができると楽しいですね!

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3