【Terraform】Terraformで構築したEC2インスタンスを手動で停止・終了(削除)するとどうなるか確認する

Terraformで構築したEC2インスタンスをAWS管理コンソールから(GUI)から手動で停止・終了(削除)した場合の挙動について確認しました。

理由は事前に「当然こうなるだろうな」と仮説を立てていましたが、本当に仮説通りになるのか念のため確かめたかったということがあります。

(ちなみに、当然こうなるだろうなと思って作業したらそうならなくて障害が発生した経験もあるので実際にやってみないと判断が付かないということもあります)

 

EC2のtfファイル

以下が EC2 インスタンスの tf ファイルです。

 

■ファイル名:Ec2.tf

resource “aws_instance” “ansible-test-ec2” { 
  ami           = “ami-0f36dcfcc94112ea1” 
  instance_type = “t2.micro” 
  subnet_id     = “subnet-0xxxxxxxxxxx”  
  tags = { 
    Name = “ansible-test-ec2” 
  } 

 

なんてこともない、単に EC2 インスタンスを起動する為の内容です。

 

 

 

terraform apply を実行して EC2 インスタンスを起動

terraform apply を実行して EC2 インスタンスを起動します。

 

 

 

手動で停止した場合

EC2 インスタンスが起動している状態で AWS 管理コンソールから手動で EC2 インスタンスを停止します。

 

 

 

 

ステータスが「停止済み」になっていることを確認します。

 

 

 

 

 

terraform plan を実行する

この状態で terraform plan を実行します。

 

結論から言えば terraform plan を実行した所、「no change」になりました。

 

■terraform plan コマンド実行

$ terraform plan 
data.aws_iam_policy_document.ec2-assume-policy-document: Reading… 

 

~ 省略 ~

 

aws_instance.ansible-test-ec2: Refreshing state… [id=i-xxxxxxxxxxxxx] 
 
No changes. Your infrastructure matches the configuration. 
 
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. 
$  

 

 

ここで普段では全く気にしていないですが、今回の検証で気になる一文を見つけました。

「Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. 」

日本語に訳すと「Terraform は 実際の インフラストラクチャ と 構成 を比較しましたが 違いは見つかりませんでした。したがって 変更は 必要ありません。」です。

 

「そういえば Terraform は構成情報を tfstate ファイルで持っていて、差分を確認して追加するとか削除するとか処理を決めているんだっけ」と思い、早速 tfstate ファイルを確認しました。

 

■tfstateファイルの EC2 インスタンスの部分

    { 
      “mode”: “managed”, 
      “type”: “aws_instance”, 
      “name”: “ansible-test-ec2”, 
      “provider”: “provider[\”registry.terraform.io/hashicorp/aws\”]”, 
      “instances”: [ 
        { 
          “schema_version”: 1, 
          “attributes”: { 
            “ami”: “ami-0f36dcfcc94112ea1”, 
            “arn”: “arn:aws:ec2:ap-northeast-1:xxxxxxxxxxxxxxxxxx:instance/i-xxxxxxxxxxxxxx”, 
            “associate_public_ip_address”: true, 
            “availability_zone”: “ap-northeast-1c”, 
            “capacity_reservation_specification”: [ 
              { 
                “capacity_reservation_preference”: “open”, 
                “capacity_reservation_target”: [] 
              } 
            ], 
            “cpu_core_count”: 1, 
            “cpu_threads_per_core”: 1, 
            “credit_specification”: [ 
              { 
                “cpu_credits”: “standard” 
              } 
            ], 
            “disable_api_stop”: false, 
            “disable_api_termination”: false, 
            “ebs_block_device”: [], 
            “ebs_optimized”: false, 
            “enclave_options”: [ 
              { 
                “enabled”: false 
              } 
            ], 
            “ephemeral_block_device”: [], 
            “get_password_data”: false, 
            “hibernation”: false, 
            “host_id”: null, 
            “host_resource_group_arn”: null, 
            “iam_instance_profile”: “ec2-instance-profile”, 
            “id”: “i-xxxxxxxxxxxxxx”, 
            “instance_initiated_shutdown_behavior”: “stop”, 
            “instance_state”: “running”,  ← 実際は停止しているが tfstate ファイル上では「running」になっている。
            “instance_type”: “t2.micro”, 
            “ipv6_address_count”: 0, 
            “ipv6_addresses”: [], 
            “key_name”: “”, 
            “launch_template”: [], 
            “maintenance_options”: [ 
              { 
                “auto_recovery”: “default” 
              } 
            ], 
            “metadata_options”: [ 
              { 
                “http_endpoint”: “enabled”, 
                “http_put_response_hop_limit”: 1, 
                “http_tokens”: “optional”, 
                “instance_metadata_tags”: “disabled” 
              } 
            ], 
            “monitoring”: false, 
            “network_interface”: [], 
            “outpost_arn”: “”, 
            “password_data”: “”, 
            “placement_group”: “”, 
            “placement_partition_number”: null, 
            “primary_network_interface_id”: “eni-xxxxxxxxxxxxxxxx”, 
            “private_dns”: “ip-xxxxxxxxxxx.ap-northeast-1.compute.internal”, 
            “private_dns_name_options”: [ 
              { 
                “enable_resource_name_dns_a_record”: false, 
                “enable_resource_name_dns_aaaa_record”: false, 
                “hostname_type”: “ip-name” 
              } 
            ], 
            “private_ip”: “xxxxxxxxxx”, 
            “public_dns”: “ec2-xxxxxxxxxx.ap-northeast-1.compute.amazonaws.com”, 
            “public_ip”: “xxxxxxxxxx”, 
            “root_block_device”: [ 
              { 
                “delete_on_termination”: true, 
                “device_name”: “/dev/xvda”, 
                “encrypted”: true, 
                “iops”: 100, 
                “kms_key_id”: “arn:aws:kms:ap-northeast-1:xxxxxxxxxxxxxx:key/xxxxxxxxxxxxxxxxxx”, 
                “tags”: {}, 
                “throughput”: 0, 
                “volume_id”: “vol-xxxxxxxxxxxxxxxx”, 
                “volume_size”: 8, 
                “volume_type”: “gp2” 
              } 
            ], 
            “secondary_private_ips”: [], 
            “security_groups”: [ 
              “default” 
            ], 
            “source_dest_check”: true, 
            “subnet_id”: “subnet-xxxxxxxxxxxxxxxxx”, 
            “tags”: { 
              “Name”: “ansible-test-ec2” 
            }, 
            “tags_all”: { 
              “Name”: “ansible-test-ec2” 
            }, 
            “tenancy”: “default”, 
            “timeouts”: null, 
            “user_data”: null, 
            “user_data_base64”: null, 
            “user_data_replace_on_change”: false, 
            “volume_tags”: null, 
            “vpc_security_group_ids”: [ 
              “sg-xxxxxxxxxxxxxxxxx” 
            ] 
          }, 
          “sensitive_attributes”: [], 
          “private”: “xxxxxxxxxxxxxxxxxxx”, 
          “dependencies”: [ 
            “aws_iam_instance_profile.ssm-agent-for-ec2” 
          ] 
        } 
      ] 
    },

 

 

気になったのが「”instance_state”: “running”」の部分です。

実際は AWS 管理コンソール画面より手動で停止しているのですが、tfstate ファイル上では「running」になっています。

さすがに適宜手動での設定変更について情報を更新していくのは不可能ということでしょう。

GUI での操作により Terraform の管理情報と現実とでズレが生じるということが分かります。

 

 

当然、terraform applyコマンドを実行しても何も処理はされません。「no change」です。

 

 

EC2インスタンスを終了(削除)した場合

次に AWS 管理画面より手動で EC2 インスタンスを終了(削除)した場合を試してみます。

 

現在停止状態になっている対象の EC2 インスタンスを終了(削除)します。

 

 

 

 

ステータスが「終了済み」になっていることを確認します。

 

 

 

terraform plan を実行する

この状態で terraform plan コマンドを実行します。

EC2 インスタンスを終了(削除)した場合は terraform plan を実行すると新規EC2インスタンスのcreateが表示が出てきます。

 

 

 

■terraform plan コマンドを実行

$ terraform plan 
aws_s3_bucket.ansible_dev_zip_bucket: Refreshing state… [id=ansible-dev-zip-bucket-xxxxxxxxx] 

 

~ 省略 ~

 

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: 
  + create 
 
Terraform will perform the following actions: 
 
  # aws_instance.ansible-test-ec2 will be created 
  + resource “aws_instance” “ansible-test-ec2” { 
      + ami                                  = “ami-0f36dcfcc94112ea1” 
      + arn                                  = (known after apply) 
      + associate_public_ip_address          = (known after apply) 
      + availability_zone                    = (known after apply) 
      + cpu_core_count                       = (known after apply) 
      + cpu_threads_per_core                 = (known after apply) 
      + disable_api_stop                     = (known after apply) 
      + disable_api_termination              = (known after apply) 
      + ebs_optimized                        = (known after apply) 
      + get_password_data                    = false 
      + host_id                              = (known after apply) 
      + host_resource_group_arn              = (known after apply) 
      + iam_instance_profile                 = “ec2-instance-profile” 
      + id                                   = (known after apply) 
      + instance_initiated_shutdown_behavior = (known after apply) 
      + instance_state                       = (known after apply) 
      + instance_type                        = “t2.micro” 
      + ipv6_address_count                   = (known after apply) 
      + ipv6_addresses                       = (known after apply) 
      + key_name                             = (known after apply) 
      + monitoring                           = (known after apply) 
      + outpost_arn                          = (known after apply) 
      + password_data                        = (known after apply) 
      + placement_group                      = (known after apply) 
      + placement_partition_number           = (known after apply) 
      + primary_network_interface_id         = (known after apply) 
      + private_dns                          = (known after apply) 
      + private_ip                           = (known after apply) 
      + public_dns                           = (known after apply) 
      + public_ip                            = (known after apply) 
      + secondary_private_ips                = (known after apply) 
      + security_groups                      = (known after apply) 
      + source_dest_check                    = true 
      + subnet_id                            = “subnet-xxxxxxxxxxx” 
      + tags                                 = { 
          + “Name” = “ansible-test-ec2” 
        } 
      + tags_all                             = { 
          + “Name” = “ansible-test-ec2” 
        } 
      + tenancy                              = (known after apply) 
      + user_data                            = (known after apply) 
      + user_data_base64                     = (known after apply) 
      + user_data_replace_on_change          = false 
      + vpc_security_group_ids               = (known after apply) 
 
      + capacity_reservation_specification { 
          + capacity_reservation_preference = (known after apply) 
 
          + capacity_reservation_target { 
              + capacity_reservation_id                 = (known after apply) 
              + capacity_reservation_resource_group_arn = (known after apply) 
            } 
        } 
 
      + ebs_block_device { 
          + delete_on_termination = (known after apply) 
          + device_name           = (known after apply) 
          + encrypted             = (known after apply) 
          + iops                  = (known after apply) 
          + kms_key_id            = (known after apply) 
          + snapshot_id           = (known after apply) 
          + tags                  = (known after apply) 
          + throughput            = (known after apply) 
          + volume_id             = (known after apply) 
          + volume_size           = (known after apply) 
          + volume_type           = (known after apply) 
        } 
 
      + enclave_options { 
          + enabled = (known after apply) 
        } 
 
      + ephemeral_block_device { 
          + device_name  = (known after apply) 
          + no_device    = (known after apply) 
          + virtual_name = (known after apply) 
        } 
 
      + maintenance_options { 
          + auto_recovery = (known after apply) 
        } 
 
      + metadata_options { 
          + http_endpoint               = (known after apply) 
          + http_put_response_hop_limit = (known after apply) 
          + http_tokens                 = (known after apply) 
          + instance_metadata_tags      = (known after apply) 
        } 
 
      + network_interface { 
          + delete_on_termination = (known after apply) 
          + device_index          = (known after apply) 
          + network_card_index    = (known after apply) 
          + network_interface_id  = (known after apply) 
        } 
 
      + private_dns_name_options { 
          + enable_resource_name_dns_a_record    = (known after apply) 
          + enable_resource_name_dns_aaaa_record = (known after apply) 
          + hostname_type                        = (known after apply) 
        } 
 
      + root_block_device { 
          + delete_on_termination = (known after apply) 
          + device_name           = (known after apply) 
          + encrypted             = (known after apply) 
          + iops                  = (known after apply) 
          + kms_key_id            = (known after apply) 
          + tags                  = (known after apply) 
          + throughput            = (known after apply) 
          + volume_id             = (known after apply) 
          + volume_size           = (known after apply) 
          + volume_type           = (known after apply) 
        } 
    } 
 
Plan: 1 to add, 0 to change, 0 to destroy. 
 
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 
 
Note: You didn’t use the -out option to save this plan, so Terraform can’t guarantee to take exactly these actions if you run “terraform apply” now. 
$  

 

 

 

先ほど同様に tfstate ファイルの内容を確認します。

 

tfstate ファイルを確認して仮説と違っていたのは、tfstate ファイルに削除した EC2 インスタンスの情報があったことです!

最初は「現実には EC2 インスタンスは存在していないから terraform plan コマンドを実行したタイミングで terraform は現実の設定を見て EC2 インスタンスがないことをチェックして tfstate ファイルが更新されて、その結果 terraform plan コマンドを実行すると create が出てくるんだろうな」と思っていました。

しかし実際やってみたら tfstate ファイルは全く更新されていませんでした。

もちろん、state は「running(起動中)」でした。

ということは他で管理されているということなんですね。

もうちょっと深堀したいと思います。

 

 

■tfstateファイルの EC2 インスタンスの部分

    { 
      “mode”: “managed”, 
      “type”: “aws_instance”, 
      “name”: “ansible-test-ec2”, 
      “provider”: “provider[\”registry.terraform.io/hashicorp/aws\”]”, 
      “instances”: [ 
        { 
          “schema_version”: 1, 
          “attributes”: { 
            “ami”: “ami-0f36dcfcc94112ea1”, 
            “arn”: “arn:aws:ec2:ap-northeast-1:xxxxxxxxxxxxxxxxxx:instance/i-xxxxxxxxxxxxxx”, 
            “associate_public_ip_address”: true, 
            “availability_zone”: “ap-northeast-1c”, 
            “capacity_reservation_specification”: [ 
              { 
                “capacity_reservation_preference”: “open”, 
                “capacity_reservation_target”: [] 
              } 
            ], 
            “cpu_core_count”: 1, 
            “cpu_threads_per_core”: 1, 
            “credit_specification”: [ 
              { 
                “cpu_credits”: “standard” 
              } 
            ], 
            “disable_api_stop”: false, 
            “disable_api_termination”: false, 
            “ebs_block_device”: [], 
            “ebs_optimized”: false, 
            “enclave_options”: [ 
              { 
                “enabled”: false 
              } 
            ], 
            “ephemeral_block_device”: [], 
            “get_password_data”: false, 
            “hibernation”: false, 
            “host_id”: null, 
            “host_resource_group_arn”: null, 
            “iam_instance_profile”: “ec2-instance-profile”, 
            “id”: “i-xxxxxxxxxxxxxx”, 
            “instance_initiated_shutdown_behavior”: “stop”, 
            “instance_state”: “running”,  ← 実際は停止しているが tfstate ファイル上では「running」になっている。
            “instance_type”: “t2.micro”, 
            “ipv6_address_count”: 0, 
            “ipv6_addresses”: [], 
            “key_name”: “”, 
            “launch_template”: [], 
            “maintenance_options”: [ 
              { 
                “auto_recovery”: “default” 
              } 
            ], 
            “metadata_options”: [ 
              { 
                “http_endpoint”: “enabled”, 
                “http_put_response_hop_limit”: 1, 
                “http_tokens”: “optional”, 
                “instance_metadata_tags”: “disabled” 
              } 
            ], 
            “monitoring”: false, 
            “network_interface”: [], 
            “outpost_arn”: “”, 
            “password_data”: “”, 
            “placement_group”: “”, 
            “placement_partition_number”: null, 
            “primary_network_interface_id”: “eni-xxxxxxxxxxxxxxxx”, 
            “private_dns”: “ip-xxxxxxxxxxx.ap-northeast-1.compute.internal”, 
            “private_dns_name_options”: [ 
              { 
                “enable_resource_name_dns_a_record”: false, 
                “enable_resource_name_dns_aaaa_record”: false, 
                “hostname_type”: “ip-name” 
              } 
            ], 
            “private_ip”: “xxxxxxxxxx”, 
            “public_dns”: “ec2-xxxxxxxxxx.ap-northeast-1.compute.amazonaws.com”, 
            “public_ip”: “xxxxxxxxxx”, 
            “root_block_device”: [ 
              { 
                “delete_on_termination”: true, 
                “device_name”: “/dev/xvda”, 
                “encrypted”: true, 
                “iops”: 100, 
                “kms_key_id”: “arn:aws:kms:ap-northeast-1:xxxxxxxxxxxxxx:key/xxxxxxxxxxxxxxxxxx”, 
                “tags”: {}, 
                “throughput”: 0, 
                “volume_id”: “vol-xxxxxxxxxxxxxxxx”, 
                “volume_size”: 8, 
                “volume_type”: “gp2” 
              } 
            ], 
            “secondary_private_ips”: [], 
            “security_groups”: [ 
              “default” 
            ], 
            “source_dest_check”: true, 
            “subnet_id”: “subnet-xxxxxxxxxxxxxxxxx”, 
            “tags”: { 
              “Name”: “ansible-test-ec2” 
            }, 
            “tags_all”: { 
              “Name”: “ansible-test-ec2” 
            }, 
            “tenancy”: “default”, 
            “timeouts”: null, 
            “user_data”: null, 
            “user_data_base64”: null, 
            “user_data_replace_on_change”: false, 
            “volume_tags”: null, 
            “vpc_security_group_ids”: [ 
              “sg-xxxxxxxxxxxxxxxxx” 
            ] 
          }, 
          “sensitive_attributes”: [], 
          “private”: “xxxxxxxxxxxxxxxxxxx”, 
          “dependencies”: [ 
            “aws_iam_instance_profile.ssm-agent-for-ec2” 
          ] 
        } 
      ] 
    },

 

tfstate 上では EC2 インスタンスは存在している。しかし terraform plan コマンドを実行すると「create」で出てくる。

そして terraform apply コマンドを実行すると実際に EC2 インスタンスが作成されます。

 

実際にやってみると仮設とは全く異なる結果になりました。

 

 

 

 

 

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

AlphaOmega Captcha Medica  –  What Do You See?
     
 

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください