【小ネタ】AWS CDK を使って ECS に LoadBalancer に独自ドメインを設定した話

# 概要

`AWS CDK for Golang` を使って `AWS` の `ECS` のクラスタにロードバランサを設定し、そのロードバランサに独自のドメインを設定します。

# この記事で伝えたいこと

* `AWS CDK` を使うことで、簡単にロードバランサの設定を行うことができる

# 課題を解決する技術、手法

こんな感じのコードを書きます。

```go
import (
	"fmt"

	"github.com/aws/aws-cdk-go/awscdk/v2/awscertificatemanager"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsecr"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsecs"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsecspatterns"
	"github.com/aws/aws-cdk-go/awscdk/v2/awselasticloadbalancingv2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsiam"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsroute53"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

func CreateECS(scope constructs.Construct, vpc awsec2.Vpc) {
	clusterProps := awsecs.ClusterProps{
		ClusterName: jsii.String(configuration.Cluster.Name),
		Vpc:         vpc,
	}
	ecsCluster := awsecs.NewCluster(scope, jsii.String("id-cluster"), &clusterProps)
    certificateArn := "arn:aws:acm:ap-northeast-1:123456789012:certificate/f3041ca9-0651-4a65-9c34-35936ecfd222"
	certificate := awscertificatemanager.Certificate_FromCertificateArn(scope, jsii.String("id-certificate"), jsii.String(certificateArn))
	hostedZoneQuery := awsroute53.HostedZoneProviderProps{
		DomainName: jsii.String("ijufumi.net"),
	}
	repository := awsecr.Repository_FromRepositoryName(scope, jsii.String("id-ecr-repository"), jsii.String("test-repository"))
	image := awsecs.ContainerImage_FromEcrRepository(repository, jsii.String("0.0.1"))

	ecsTaskRole := awsiam.NewRole(scope, jsii.String("ecs-task-role"), &awsiam.RoleProps{
		AssumedBy: awsiam.NewServicePrincipal(jsii.String("ecs-tasks.amazonaws.com"), &awsiam.ServicePrincipalOpts{}),
	})
	ecsServiceProps := awsecspatterns.ApplicationLoadBalancedFargateServiceProps{
		Cluster:            ecsCluster,
		DesiredCount:       jsii.Number(1),
		ListenerPort:       jsii.Number(443),
		RedirectHTTP:       jsii.Bool(true),
		PublicLoadBalancer: jsii.Bool(true),
		Protocol:           awselasticloadbalancingv2.ApplicationProtocol_HTTPS,
		DomainName:         jsii.String("test-domain.ijufumi.net"),
		DomainZone:         awsroute53.PublicHostedZone_FromLookup(scope, jsii.String(fmt.Sprintf("zone-id")), &hostedZoneQuery),
		Certificate:        certificate,
		TaskSubnets: &awsec2.SubnetSelection{
			Subnets: vpc.PrivateSubnets(),
		},
		TaskImageOptions: &awsecspatterns.ApplicationLoadBalancedTaskImageOptions{
			Image:         image,
			ContainerPort: jsii.Number(8080),
			TaskRole: ecsTaskRole,
		},
	}
	ecsServiceID := fmt.Sprintf("ecs-service-%s", configuration.Cluster.Name)
	awsecspatterns.NewApplicationLoadBalancedFargateService(scope, jsii.String(ecsServiceID), &ecsServiceProps)
}
```

## 技術、手法の概要

* SSL証明書は、予め `Certificate Manager` で発行
  * その `ARN` を `certificateArn` に設定
* `ijufumi.net` のドメインを `Route53` 登録
* `ECS` にデプロイする `docker` イメージを格納する `ECR` は、予め作成
  * イメージも予め `push` する
* `ApplicationLoadBalancedFargateServiceProps` を使って、 `ALB` を設定
  *  `Listen` するポートは `443`
  *  `LoadBalancer` を外部に公開
  *  `ALB` に設定するドメイン名とSSL証明書を指定

# 留意点、デメリット

`ECS` にデプロイする `docker` イメージ及びそれを格納する `ECR` の作成も `CDK` で作成することができるかなと思います。