最近、ECS on FargateとELB(ALB)を新しく構築しました。基本的にリソースはTerraformでコード管理しているのですが、ECSのタスク定義とサービスについてはデプロイごとに更新が必要(ライフサイクルが短い)なので、ecspressoというOSSで管理しています。
ELBについては一度構築すれば滅多に更新されることはないと思っていたのですが、今回Blue/Greenデプロイを導入したら、リスナールールのターゲットグループがデプロイごとに変わることがわかりました。これだとTerraformの構成ファイルと実際のリソースで差分が出てしまい、他のリソースを作成・更新する際にその差分が乗っかってきてしまいます。
この問題を解決するために、まずは「ターゲットグループを動的に読み込む」といった方法が思い浮かんだのですが、Terraformの構成が複雑になりそうな気がしたので、更新頻度が高いリソースに対しては、「リスナールールをTerraformの管理から一時的に外し、必要に応じて管理下に戻す」という方法を選びました。
Terraform管理からリソースを外す手順
modules/elb/main.tf
で以下のリスナールールを管理しているとします。
resource "aws_lb_listener_rule" "blue" {
listener_arn = aws_lb_listener.https_443.arn
priority = 100
action {
type = "forward"
target_group_arn = aws_lb_target_group.target_blue.arn
}
condition {
host_header {
values = ["dev.example.jp"]
}
}
}
terraform apply
を行っているディレクトリで以下のコマンドを実行すると、Terraformのステートファイルからこのリスナールールが削除されます。
$ terraform state rm module.elb.aws_lb_listener_rule.blue
最後にリスナールールをコメントアウトするか削除することで、次回のterraform apply
にリスナールールの変更が影響されなくなります。
Terraform管理下にリソースを戻す方法
リスナーのARNをコンソールから確認して、AWS CLIでリスナールールのARNを特定します。
$ aws elbv2 describe-rules --listener-arn [リスナーのARN]
以下のように出力されるので、 RuleArn
をコピーします。
{
"Rules": [
{
"RuleArn": "arn:aws:elasticloadbalancing:ap-northeast-1:********:listener-rule/app/example-alb/********/********/********",
"Priority": "100",
"Conditions": [
{
"Field": "host-header",
"Values": [
"dev.example.jp"
],
"HostHeaderConfig": {
"Values": [
"dev.example.jp"
]
}
}
],
以下のコマンドでリソースをTerraformの管理下に戻すことができます。
$ terraform import module.elb.aws_lb_listener_rule.blue [リスナールールのARN]
おわりに
今回みたいな頻繁に更新されるリソースの管理をみなさんがどうされているのかしりたい..