どうもどうも乙カレー様です。桑野です。
びっくりするほどブログ書いてなくてびっくりしてます。半年書いてないやん。
Terraformを使っていたりするんですが、最近EC2のAutoScaleを入れようとして辛いことがあったりしたのでちょっとまとめてみます。
Terraform
Terraformは言わずとも知れたHashicorpさんのプロダクトですね。
インフラ構築をコード化してGithub等でレポジトリ管理することによって履歴管理や、プルリクエストベースの構築ができるのが売りだったりします。
TerraformでのAutoScale時のハマりどこ
端的にいうとこの2つです。
- Terraform経由で実行した際のLaunchConfiguration(イカLC)とAutoScalingGroup(イカASG)の削除の順番が逆
- LC内のuser_data更新で一網打尽になる
Terraform経由で実行した際のLaunchConfiguration(イカLC)とAutoScalingGroup(イカASG)の削除の順番が逆
何が悪いかといいますと、この2つは依存関係があるので、ASGを削除する前にそれが紐付いてるLCを削除しようとするとまだAttachされてるよってエラーが出て止まるわけです。
なので、ASG->LCの順で削除してくれればいいんだけど、実際には逆でしか動いてくれない。
* ResourceInUse: Cannot delete launch configuration launchconfig-test because it is attached to AutoScalingGroup autoscalinggroup-test status code: 400, request id: [12345678-1234-1234-1234-123412341234]
となると。
GithubのIssueとかでも同じような議論があってlifecycle { create_before_destroy = true }をつけたらいいぜって言ってる人もいるけど、作成タイミングの違いだからやっぱりうまく動かない。
LC内のuser_data更新で一網打尽になる
じゃあ2個作って交互に更新して行ったらええんちゃうんかでバージョン管理する。
これでOKでしょ。
# 古いLC resource "aws_launch_configuration" "launchconfig_test_v1" { name = "launchconfig-test-v1" image_id = "${var.amis.api}" key_name = "${var.aws.key_name}" instance_type = "t2.micro" security_groups = ["${var.security_groups.asgtest}"] iam_instance_profile = "asgtest" associate_public_ip_address = 0 user_data = "${file("user_data/app_userdata.sh")}" }
# 新しいLC resource "aws_launch_configuration" "launchconfig_test_v2" { name = "launchconfig-test-v2" image_id = "${var.amis.api}" key_name = "${var.aws.key_name}" instance_type = "t2.micro" security_groups = ["${var.security_groups.asgtest}"] iam_instance_profile = "asgtest" associate_public_ip_address = 0 user_data = "${file("user_data/app_userdata.sh")}" }
ぼくが気付かなかっただけだけど、この場合はuser_data/app_userdata.shが更新されるとどっちも再作成になって⊂ミ⊃^ω^ )⊃ アウアウ!!
* ResourceInUse: Cannot delete launch configuration launchconfig-test because it is attached to AutoScalingGroup autoscalinggroup-test-v1 status code: 400, request id: [12345678-1234-1234-1234-123412341234]
TerraformでのAutoScale時する時のベストプラクティス?
じゃあどうしたらいいんだって話ですが、一旦色々考えたり話したりした挙句こんな感じになりました。
- ASG, LC, user_dataはバージョニングする
- 追加/削除時の作業順を厳密に指定する
- 1. user_data作成
- 2. 新LC, ASG作成
- 3. 旧ASGの desired_capacity を0にして既存系のインスタンス削除する
- 4. 旧ASGを削除する
- 5. 旧LCを削除する
この手順だと実際にApplyするのは、2. 3. 4. 5.で4回です(2. と3. はまとめられますがそれでも3回)。多いですね。
3.の時の設定の状態
# 古いLC resource "aws_launch_configuration" "launchconfig_test_v1" { name = "launchconfig-test-v1" image_id = "${var.amis.api}" key_name = "${var.aws.key_name}" instance_type = "t2.micro" security_groups = ["${var.security_groups.asgtest}"] iam_instance_profile = "asgtest" associate_public_ip_address = 0 user_data = "${file("user_data/app_userdata_v1.sh")}" }
# 古いASG(この後削除する) resource "aws_autoscaling_group" "autoscalinggroup_test_v1" { availability_zones = ["ap-northeast-1c"] name = "autoscalinggroup-test-v1" max_size = 0 min_size = 0 health_check_grace_period = 300 health_check_type = "ELB" desired_capacity = 0 force_delete = true launch_configuration = "${aws_launch_configuration.launchconfig_test_v1.id}" vpc_zone_identifier = ["${var.subnets.asgtest}""] load_balancers = ["${aws_elb.asgtest.name}"] tag = { key = "Name" value = "app-asg" propagate_at_launch = true } tag = { key = "SERVER" value = "APP" propagate_at_launch = true } }
新しい設定
# 新しいLC resource "aws_launch_configuration" "launchconfig_test_v2" { name = "launchconfig-test-v2" image_id = "${var.amis.api}" key_name = "${var.aws.key_name}" instance_type = "t2.micro" security_groups = ["${var.security_groups.asgtest}"] iam_instance_profile = "asgtest" associate_public_ip_address = 0 user_data = "${file("user_data/app_userdata_v2.sh")}" }
# 新しいASG resource "aws_autoscaling_group" "autoscalinggroup_test_v2" { availability_zones = ["ap-northeast-1c"] name = "autoscalinggroup-test-v2" max_size = 4 min_size = 2 health_check_grace_period = 300 health_check_type = "ELB" desired_capacity = 2 force_delete = true launch_configuration = "${aws_launch_configuration.launchconfig_test_v2.id}" vpc_zone_identifier = ["${var.subnets.asgtest}""] load_balancers = ["${aws_elb.asgtest.name}"] tag = { key = "Name" value = "app-asg" propagate_at_launch = true } tag = { key = "SERVER" value = "APP" propagate_at_launch = true } }
で、
この人は何故ここまで頑張ってTerraformを使う必要があるのだろうか、、、っていう部分は聞かないでください!
でもやってて開発者の人にもサーバ構成を共有するとか、インスタンス作成部分とかは作業してこっちでもプルリクエストベースでのコードレビュー(構成レビュー)させてもらえるのは非常にいいと思ってます。
そして、バージョン0.6以降で上手く使えるようになることを祈っていますね。。。
でも ↑ この時よりは状況良くなっていると思います!貢献していきたい。
- 作者: 橘賢一,貴家悠
- 出版社/メーカー: 集英社
- 発売日: 2015/05/19
- メディア: コミック
- この商品を含むブログ (87件) を見る
じょうじょ