コード化中
- AWS CDKの導入
- CodePipelineのコード化
- EventBridge Schedulerのコード化
- ECS clusterとserviceのコード化(この記事)
- ElastiCacheのコード化、本番環境構築
ECS service
サービス作成箇所です
Fargateを使用しています
rescources/api/Ecs.kt
fun createService() {
val securityGroupId = context["apiSecurityGroup"].toString()
val securityGroup = SecurityGroup.fromLookupById(scope, "developmentMyappApiCdkSecurityGroup", securityGroupId)
val subnet1 = context["apiSubnet1"].toString()
val subnet2 = context["apiSubnet2"].toString()
val routeTableId = context["apiRouteTable"].toString()
val vpcSubnets = SubnetSelection.builder()
.subnets(listOf(
Subnet.fromSubnetAttributes(
scope,
"developmentMyappApiCdkSubnet1",
SubnetAttributes.builder()
.subnetId(subnet1)
.routeTableId(routeTableId)
.build()),
Subnet.fromSubnetAttributes(
scope,
"developmentMyappApiCdkSubnet2",
SubnetAttributes.builder()
.subnetId(subnet2)
.routeTableId(routeTableId)
.build())
))
.build()
service = FargateService.Builder
.create(scope, "developmentMyappApiCdkEcsService")
.serviceName("api")
.cluster(ecsCluster)
.taskDefinition(taskDefinition)
.desiredCount(1)
.minHealthyPercent(100)
.maxHealthyPercent(200)
.securityGroups(listOf(securityGroup))
.vpcSubnets(vpcSubnets)
.healthCheckGracePeriod(Duration.minutes(0))
.enableEcsManagedTags(true)
.assignPublicIp(true)
.build()
val albTargetGroupArn = context["apiAlbTargetGroupArn"].toString()
val albTargetGroup = ApplicationTargetGroup.fromTargetGroupAttributes(
scope,
"developmentMyappApiCdkAlbTargetGroup",
TargetGroupAttributes.builder()
.targetGroupArn(albTargetGroupArn)
.build()
)
service.attachToApplicationTargetGroup(albTargetGroup)
}
ECS cluster
service作成時にclusterが必要になるので全体に共通するリソース用のstackを追加してclusterを作成します
vpcはすでに作成してあるリソースを取得するようにします
InfraStack.kt
class InfraStack(
parent: Construct, name: String, stackProps: StackProps
): Stack(parent, name, stackProps) {
var ecsCluster: Cluster
init {
val context = this.getNode().tryGetContext("development") as Map<String, Any>
val vpc = Vpc(this, context)
vpc.getVpc()
val ecs = Ecs(this, context)
ecs.createCluster(vpc.vpc)
ecsCluster = ecs.cluster
}
}
recources/infra/Vpc.kt
class Vpc(val scope: Construct, val context: Map<String, Any>) {
lateinit var vpc: IVpc
fun getVpc() {
val vpcId = context["vpcId"].toString()
vpc = Vpc.fromLookup(
scope,
"developmentMyappAdminCdkVpc",
VpcLookupOptions.builder()
.vpcId(vpcId)
.build()
)
}
}
recources/infra/Ecs.kt
class Ecs(val scope: Construct, val context: Map<String, Any>) {
lateinit var cluster: Cluster
fun createCluster(vpc: IVpc) {
cluster = Cluster.Builder
.create(scope, "developmentMyappInfraCdkCluster")
.clusterName("developmentMyappInfraCdkCluster")
.containerInsights(true)
.vpc(vpc)
.enableFargateCapacityProviders(true)
.build()
}
}
vpc取得時のLookUpを実行するために cdk ls
などを実行した際に作成される cdk.context.json
をコミットします
管理画面用のリポジトリ
API用とほぼ同じなのでcdk.jsonの定義追加してあとはほぼコピペです
依存関係
全体に共通するリソース用のStackを作成したので、stack間に依存関係ができました
依存関係が守られるように DeployStage.kt
で addDependency
を設定します
DeployStage.kt
val infraStack = InfraStack(this, "developmentMyappInfraCdkInfraDeployStack", stackProps)
AdminStack(this, "developmentMyappInfraCdkAdminDeployStack",
stackProps,
infraStack.ecsCluster)
.addDependency(infraStack)
ApiStack(this, "developmentMyappInfraCdkApiDeployStack",
stackProps,
infraStack.ecsCluster)
.addDependency(infraStack)
BatchStack(this, "developmentMyappInfraCdkBatchDeployStack",
stackProps,
infraStack.ecsCluster.getClusterArn())
.addDependency(infraStack)
これをデプロイすると、InfraStackが先に実行され、ApiStack、AdminStack、BatchStackはInfraStackが完了してから並列で実行されるようになります
次回
ElastiCacheのコード化と本番環境の構築です