【AWS】CDKでECS Clusterを構築しよう


【AWS】CDKでECRを構築しようのECS Clusterバージョンです
前提などは省きますので前回の記事を参照してください

環境

インストール

pipenv install aws_cdk.aws_ec2 aws_cdk.aws_ecs

実装

props/ecs_cluster.py

ECS Clusterを作成する時に既存のVPCを利用したい場合は、VPC IDをもとにルックアップして既存VPCをStack内で利用できるようにする必要があります。そのためVpcForEcsClusterというクラスでパラメータ管理をします。

あとはAPI Referenceを参照しながら、設定可能なパラメータを定義しています。Container Insightsは有効化しておいた方が監視で役に立つので、デフォルトでTrueにしてあります。

props/ecs_cluster.py
from dataclasses import dataclass
from typing import Optional

from aws_cdk.aws_ecs import CloudMapNamespaceOptions

from src.props.base import Base


@dataclass(frozen=True)
class VpcForEcsCluster(Base):
    id: str
    vpc_id: str


@dataclass(frozen=True)
class EcsCluster(Base):
    id: str
    cluster_name: str
    container_insights: bool = True
    default_cloud_map_namespace: Optional[CloudMapNamespaceOptions] = None

entity/ecs_cluster.py

ECS Clusterの場合は環境によってパラメータが違う、具体的にいうとVPC IDが異なるので環境ごとのentityを作成します。今回はステージングだけを書いていますが、本番の場合は同じファイルにProdEcsClusterクラスを定義すればいいでしょう。

entity/ecs_cluster.py
from src.entity.base import Base
from src.props.ecs_cluster import EcsCluster, VpcForEcsCluster


class EcsClusterBase(Base):
    vpc: VpcForEcsCluster
    cluster: EcsCluster


class StgEcsCluster(EcsClusterBase):
    id = 'StgEcsCluster'

    vpc = VpcForEcsCluster(
        id='StgVpc',
        vpc_id='vpc-xxxxxxxx'
    )

    cluster = EcsCluster(
        id='StgEcsCluster',
        cluster_name='sample'
    )

stack/ecs_cluster.py

stackはどの環境でも使いまわせるようになっています。

Clusterでは、既存VPCを利用したい場合は引数にvpcの指定が必要なのでVpc.from_lookupというクラスメソッドを利用して、VPC IDをもとに取得しています。

stack/ecs_cluster.py
from typing import Any, Type

from aws_cdk.aws_ec2 import Vpc
from aws_cdk.aws_ecs import Cluster
from aws_cdk.core import Construct, Stack

from src.entity.ecs_cluster import EcsClusterBase


class EcsClusterStack(Stack):
    def __init__(
            self,
            scope: Construct,
            entity: Type[EcsClusterBase],
            **kwargs: Any) -> None:
        super().__init__(scope, entity.id, **kwargs)

        vpc = Vpc.from_lookup(self, **entity.vpc.to_dict())
        Cluster(self, **entity.cluster.to_dict(), vpc=vpc)

app.py

それではapp.pyに構築したいリソースのスタックを追加しましょう。
既存VPCを利用してECS Clusterを構築したい場合は、region/accountの環境設定もEcsClusterStackに渡してあげます。CDKが自動でContextを作成して、デプロイ時に変更されるとまずいデータ(今回は既存VPC)を保持してくれます。キャッシュ的な意味もあります。

app.py
#!/usr/bin/env python3

from aws_cdk import core

from src.entity.ecr import SampleEcr
from src.entity.ecs_cluster import StgEcsCluster
from src.stack.ecr import EcrStack
from src.stack.ecs_cluster import EcsClusterStack

app = core.App()

# 全てのリソースに設定するタグ
tags = {'CreatedBy': 'iscream'}

# 環境設定 (既存VPCを利用するために必須)
env_stg = {'region': 'ap-northeast-1', 'account': 'xxxxxxxx'}

# 前回作成したECR
EcrStack(app, entity=SampleEcr, tags=tags)

# ECS Cluster
EcsClusterStack(app, StgEcsCluster, tags=tags, env=env_stg)

app.synth(skip_validation=False)

デプロイ

いざ、デプロイ!!!

pipenv run cdk deploy StgEcsCluster

Reference