🛕

EC2 パブリックIPアドレス無効化はTerraform一択だったかもしれない

2023/08/02に公開

こんにちは。
ご機嫌いかがでしょうか。
"No human labor is no human error" が大好きな吉井 亮です。

AWS パブリックIPアドレス 料金体系変更に対応する作業 EC2編 の対応を考えています。
AWS Backup からリストア、AMI から手動でリストアなど方法はいくらでもあるのですが、シンプルでミスが少ない方法を模索しています。

今回は Terraform の import ブロックを活用してみます。
感動に近いレベルで本作業に最適なツールです。

Terraform import ブロック

import ブロックは Terraform 1.5 の新機能です。

1.5より以前から import 機能は実装されていました。import ブロックになって何が嬉しいかというと、インポートしたリソースの TF ファイルを作ってくれます。
1.5より以前は予めリソースブロックを定義しておいて import コマンドでインポートをしていたので、手間が圧倒的に違います。

インポートしてみる

既存 EC2 インスタンスをインポートしてみます。

どうせなので最新バージョンを使います。

$ terraform --version
Terraform v1.5.4

Provider.tf を簡単に書きます。

Provider.tf
terraform {
  required_version = ">= 1.5.4"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.6.2"
    }
  }

  backend "s3" {
    bucket  = "your-bucket-name"
    region  = "your-region"
    key     = "import-test/terraform.tfstate"
    encrypt = true
  }
}

// Configure the AWS Provider
provider "aws" {
  region  = "your-region"
}

今回 import ブロックは import.tf ファイルを作りました。
id に AWS リソースを to に Terraform リソースを指定します。

import.tf
import {
  id = "your-instance-id"
  to = aws_instance.source
}

terraform initterraform plan を実行します。
plan のオプション -generate-config-out=generated.tf は出力先の TF ファイルです。

$ terraform init
$ terraform plan -generate-config-out=generated.tf

生成されたTFファイルの編集

-generate-config-out=generated.tf で生成された TF ファイルを少し編集します。
編集箇所は以下です。

generated.tf
  // ipv6_address_count と共存できないためコメントアウト
  #ipv6_addresses                       = []

  // 最終行に追記
  // インポートしたリソースを誤って操作してしまわないようにおまじない
  lifecycle {
    ignore_changes = all
  }

Stateへ反映

import ブロックに書いて terraform plan しただけでは State へ反映されません。
terraform apply で State へ反映します。

$ terraform apply
〜略〜
aws_instance.source: Importing... [id=i-xxxx]
aws_instance.source: Import complete [id=i-xxxx]
aws_instance.source: Modifying... [id=i-xxxx]
aws_instance.source: Modifications complete after 3s [id=i-xxxx]

Apply complete! Resources: 1 imported, 0 added, 1 changed, 0 destroyed.

AMI 作成

この後、インスタンスを複製するので AMI を取得します。
難しいことはなくサクッと取得してしまってください。

パブリックIPアドレスを無効にして複製

パブリック IP アドレスを無効にしたインスタンスを複製します。
generated.tf を別名でコピーします。今回は ec2.tf にしました。
ec2.tf を複製用に編集します。編集箇所だけ抜粋します。

ec2.tf
// リソース名
resource "aws_instance" "new" {
  ami                                  = "ami-xxxxxxxxxxxxxxxxx"    // 前の手順で取得した AMI
  associate_public_ip_address          = false                      // パブリック IP アドレス無効
  private_ip                           = "10.0.4.100"               // 現存する全 AWS リソースと重複しないプライベート IP アドレス、行削除でもいい
}

編集内容をよく確認します。誤って既存リソースに影響を出さないように気をつけます。
terraform plan でも同様に慎重なチェックを忘れずに。

$ terraform plan

$ terraform apply

しばらくすると複製されたインスタンスが起動します。
驚くほどシンプルにパブリック IP アドレスを無効にしました。

まとめ

Terraform の新機能を使ってパブリック IP アドレスを無効にしました。
パブリック IP アドレスの課金自体はそこまで神経質になることではありませんが、対象のリソースが多すぎるシステムでは手当ては必要だと思います。

Discussion