🟪

既存 AWS リソースを Terraform 化するハンズオン

2022/10/23に公開

Terraform 化するリソースを手動で作成する

今回の例では、example-group に所属する example-user を Terraform 化する。
まずは Terraform 化する AWS リソースを AWS CLI で作成する。

# IAM グループ作成
aws iam create-group --group-name example-group

# IAM ユーザー作成
aws iam create-user --user-name example-user

# IAM グループにユーザーを追加
aws iam add-user-to-group \
  --group-name example-group \
  --user-name example-user

Terraform リソースの特定

Terraform 化するにあたって、最初に対象リソースがどの Terraform リソースに相当するかを調べる。
Terraform の AWS Provider のリファレンス で IAM 関連のリソースを調べて特定する。

今回の例では、以下の3つの Terraform リソースに相当する。

Terraform 作業ディレクトリの初期化

任意のディレクトリを Terraform の作業ディレクトリとして扱う。
以降の手順は、Terraform 作業ディレクトリで行う。

.tf ファイル作成

使用する Terraform リソースを定義した .tf ファイルを作成する。
resource "resource_name" "local_name" {} の形式で、前の手順で調べたリソースを定義する。
まずは、main.tf というファイルにまとめて定義する。

main.tf
resource "aws_iam_group" "example_group" {}

resource "aws_iam_user" "example_user" {}

resource "aws_iam_user_group_membership" "example_user" {}

terraform init

ファイルを作成したら terraform init を実行する。
これによって Terraform を扱うために必要なプラグインがダウンロードされる。

Terraform 化

ここから本題の Terraform 化を行っていく。
本ハンズオンでは、Terraform CLI を用いた方法を紹介する。
https://developer.hashicorp.com/terraform/cli/commands/import

terraform import

terraform import は、定義した Terraform リソースと既存リソースを結びつけて、作業ディレクトリの tfstate に反映するコマンドである。

コマンドは terraform import [options] ADDRESS ID の形式で実行する。
ADDRESS は、.tf ファイルに記述したリソースを特定するもので、 resource_name.local_name の形式で表される。
ID は、import する既存リソースを特定するもので、形式は Terraform リソースのドキュメントの Import 節に記載されている。

今回の場合は、以下の3つのコマンドで import する。

terraform import aws_iam_group.example_group example-group

terraform import aws_iam_user.example_user example-user

terraform import aws_iam_user_group_membership.example_user example-user/example-group

これにより、Terraform 作業ディレクトリの現在の tfstate が、既存リソースを表した tfstate になる。

terraform plan で差分がない状態にする

Terraform 化できた状態とは、「.tf ファイルから生成される tfstate」と「既存リソースを表した現在の tfstate」が一致した状態である。
現状、.tf ファイルに定義した resource は空っぽであるため「現在の tfstate」とは乖離した状態である。

terraform plan コマンドを実行すると「.tf ファイルから生成される tfstate」と「現在の tfstate」との差分が表示される。
「現在の tfstate」は既存リソースと一致しているため、terraform plan コマンドで差分がなくなれば .tf ファイルで既存リソースを表現できていること(= Terraform 化できた状態)になる。

現時点で terraform plan を実行すると resource に必須項目がないためにエラーになる。
tfstate ファイルを参照しながら resource の name などの項目を埋めていく。
最終的に terraform plan の実行結果が "No changes." になれば Terraform 化は完了となる。

Terraform からリソースに変更を加える

Terraform 化できたことを確認するために、Terraform からリソースに変更を加えてみる。
試しに IAM ユーザーにリソースタグを追加する。
以下のように、ユーザーのリソースに tags を追記する。

main.tf
...
resource "aws_iam_user" "example_user" {
  name = "example-user"
+ tags = {
+   "key": "value",
+   "key2": "value2",
+ }
}
...

terraform plan すると、追記した tags が差分として表示される。
terraform apply すると変更が適用される。

いろいろ変更してみる

以下のような変更を加えると Terraform のキャッチアップにちょうどいいと思われる。

  • ユーザーを追加してみる
  • .tf ファイルを分割してみる
  • IAM グループにポリシーを追加してみる

リソースの削除

一通り遊んだらリソースを削除する。
Terraform 化できているので、terraform destroy で削除できる。
一応、tfstate ファイルを見てどのリソースが対象になっているか確認した上で実行すること。

【補足】 Config-driven import

Terraform 1.5 から config-driven import という機能が追加された。
https://www.hashicorp.com/blog/terraform-1-5-brings-config-driven-import-and-checks
https://developer.hashicorp.com/terraform/language/import

この機能を使うと既存リソースの Terraform 化が簡単に行えるようになる。
以下に、本ハンズオンを Config-driven import で行う手順を示す。
ハンズオンで使う AWS リソースは作成済みのものとする。

import の定義を作成する

以下のような import 定義を記述したファイルを作成する。
terraform import コマンドで入力したのと同じような内容になる。

import.tf
import {
  id = "example-group"
  to = aws_iam_group.example_group
}

import {
  id = "example-user"
  to = aws_iam_user.example_user
}

import {
  id = "example-user/example-group"
  to = aws_iam_user_group_membership.example_user
}

terraform init

ファイルを作成したら terraform init を実行する。

tf ファイルを生成

以下のコマンドを入力すると、import 定義の通りに AWS リソースが参照されて、Terraform リソースの定義が記述された main.tf が生成される。

terraform plan -generate-config-out=main.tf

ファイルが生成された後 terraform apply すると terraform plan で差分がない状態になる。
以上で Config-driven import を用いた Terraform 化が完了となる。

GitHubで編集を提案

Discussion