はじめに
チームには、レポートを保存するための非公開ストレージが必要です。この実験では、Terraform で最初のバケットを作成し、その設定を AWS および Terraform の状態と比較してから、削除内容を確認して実行します。別に用意された参照用レポートは他のチームの所有物なので、変更せずに残す必要があります。
Terraform のリソース、init、plan、apply、状態、destroy を理解し、ファイル編集と AWS CLI による S3 のクエリに慣れていることを前提とします。Terraform、AWS プロバイダー、CLI のアクセス設定は準備済みです。コマンドの実行には Terminal、ストレージの確認には AWS View を使用します。個人の AWS アカウントやアクセスキーは不要です。各実験は独立した環境で開始します。
認定試験との関連
| 認定資格 | 試験のタスク | 演習内容 |
|---|---|---|
| Cloud Practitioner (CLF-C02) | Task 3.1 | Infrastructure as Code による再現可能なデプロイと、CLI のクエリによる確認を行います。 |
| Developer – Associate (DVA-C02) | Task 3.3, Skill 3.3.4 | IaC のリソース定義を実装してデプロイする基礎演習です。 |
| DevOps Engineer – Professional (DOP-C02) | Task 2.1 | IaC でリソースを定義し、その作成と削除を管理する基礎演習です。 |

レポート用バケットを作成する
このステップでは、Terraform のリソース定義を現在の AWS アカウントに接続し、非公開のレポート用バケットを作成します。
まず、準備済みのルートディレクトリに移動し、リージョンと呼び出し元の ID を照会します。ルートディレクトリは、独自の状態を持つ、独立した Terraform 設定の単位です。呼び出し元のアカウントはプロバイダーのリクエストがどのアカウントで実行されるかを示し、ARN はリクエスト元の ID を識別します。
cd /home/labex/project/first-aws-resource
aws configure get region
aws sts \
get-caller-identity
terraform version
リージョンは us-east-1 です。Terraform のバージョンは 1.17.2 と表示されます。準備済みのアクセス設定は、個人の AWS アカウントとは別のものです。
用意された provider.tf は AWS プロバイダーのバージョン 6.14.0 を選択し、準備済みの接続を設定し、Terraform を 1.17.2 に固定しています。プロバイダーは、リソース操作を AWS API リクエストに変換します。リソース管理に集中できるよう、プロバイダーの設定は用意されています。
次の設定で main.tf を作成します。cat と <<'EOF' は、終端の EOF までの内容を指定したファイルに書き込みます。aws_s3_bucket は AWS リソースの種類、reports は Terraform 内でのローカルラベルです。この 2 つでアドレス aws_s3_bucket.reports を構成します。bucket 属性は AWS のバケット名であり、このアドレスとは別のものです。タグにはリソースの用途を記録します。
cat > main.tf <<'EOF'
resource "aws_s3_bucket" "reports" {
bucket = "terraform-first-reports"
tags = {
Project = "TerraformReports"
}
}
output "report_bucket" {
value = aws_s3_bucket.reports.id
}
EOF
このルートを初期化し、設定を検証します。
terraform init
terraform validate
init は準備済みのキャッシュから固定バージョンのプロバイダーをインストールし、.terraform.lock.hcl を書き込みます。実際のプロジェクトでは、この依存関係のロックファイルを設定と一緒に保持してください。選択したプロバイダーとパッケージのチェックサムが記録されています。リソースアドレスとデプロイ済みリソース ID を対応付ける Terraform の状態とは異なります。キャッシュはこの Linux 環境向けに準備されているため、init がロックファイルのチェックサムは linux_amd64 のみを対象とするという警告を出すことがありますが、初期化は完了します。他のプラットフォームでも使用するプロジェクトには、それらのプラットフォームのチェックサムも必要です。
何かを作成する前に、プランを確認します。
terraform plan
Plan: 1 to add, 0 to change, 0 to destroy. と表示されるはずです。一部の属性に (known after apply) と表示されるのは、作成時に AWS がその値を割り当てるか返すためです。バケット名とプロジェクトタグを確認してください。プランは操作のプレビューであり、バケットは作成しません。
設定を適用し、確認プロンプトで yes を入力します。
terraform apply
Apply complete! Resources: 1 added, 0 changed, 0 destroyed. と表示されるはずです。report_bucket の出力は terraform-first-reports です。AWS View では、新しい空のバケットが team-reference-reports の隣に表示されます。この参照用バケットと、その中の keep.txt オブジェクトには手を加えないでください。

コマンドを完了したら Continue を使用してください。チェックでは AWS と状態の対応付けをそれぞれ独立に照会するため、コマンドが成功しただけでは十分ではありません。
設定、状態、AWS を比較する
このステップでは、Terraform のリソースアドレスを実際の非公開バケットと対応付け、設定が収束していることを確認します。
出力はリソース参照を通じてバケット ID を読み取ります。state list は管理対象のアドレスを、state show は記録された属性を表示します。これらのコマンドは AWS を変更せずに対応付けを確認します。
terraform output report_bucket
terraform state list
terraform state show aws_s3_bucket.reports
aws_s3_bucket.reports と、その ID terraform-first-reports を確認してください。設定は望ましいリソースを表し、AWS はリソースを保持し、状態はこの 2 つを結び付けます。状態にエントリーがあるだけでは、リソースが現在も存在する証拠にはなりません。
AWS に直接照会します。get-bucket-location は、S3 の us-east-1 リージョンに対して null を返します。ACL は所有者の正規ユーザーにのみアクセスを許可し、パブリックグループへの許可がないことを確認してください。この実験では非公開バケットを作成し、公開用のバケットポリシーは追加しません。
aws s3api \
get-bucket-location \
--bucket terraform-first-reports
aws s3api \
get-bucket-acl \
--bucket terraform-first-reports
aws s3api \
get-bucket-tagging \
--bucket terraform-first-reports
Project タグが TerraformReports であることを確認します。管理対象ではないレポートも引き続き読み取れることを確認してください。--query 式はそのバイト長のみを選択し、このコマンドは保存されたオブジェクトを変更しません。
aws s3api \
head-object \
--bucket team-reference-reports \
--key keep.txt \
--query ContentLength
terraform plan
プランには No changes. と表示されるはずです。これは、管理対象リソースについてプロバイダーが設定の変更を検出していないことを意味します。あらゆるセキュリティ特性を証明したり、レポートデータを検証したりするものではなく、それぞれ別のチェックが必要です。詳しくは Terraform の状態と S3 のアクセス制御を参照してください。
管理対象のリソースだけを削除する
このステップでは、削除プランを確認して適用し、管理対象バケットと状態の対応付けがなくなり、参照用レポートが残っていることを確かめます。
terraform plan -destroy は、このルートの状態に含まれるリソースの削除をプレビューします。「アカウント内のすべてのバケットを削除する」という意味ではありません。続行する前に、アドレスとバケット ID を確認してください。
terraform plan -destroy
Plan: 0 to add, 0 to change, 1 to destroy. と表示されるはずです。参照用バケットはこのルートの管理対象ではないため、プランには含まれません。対象のバケットは空です。保存済みデータとバージョンについて別途保持の判断が必要になる理由は、後の実験で説明します。
管理対象バケットを削除し、確認プロンプトで yes を入力します。
terraform destroy
Destroy complete! Resources: 1 destroyed. と表示されるはずです。次に、状態を確認し、残っているバケットを照会します。
terraform state list
aws s3api \
list-buckets \
--query 'Buckets[].Name'
aws s3api \
head-object \
--bucket team-reference-reports \
--key keep.txt \
--query ContentLength
状態の一覧は空になります。正常に取得したバケット一覧に terraform-first-reports は含まれず、team-reference-reports とそのレポートは残っています。認証エラーを削除成功と取り違えないよう、最後のチェックが完了するまで AWS のアクセス設定を維持してください。リソースを再作成したい場合に備えて、設定とロックファイルは残っています。

まとめ
バージョンを固定した AWS プロバイダーで非公開の S3 バケットを作成し、AWS へのクエリで設定と状態を比較し、収束したプランを確認して、管理対象のリソースだけを削除しました。独立した参照用レポートはそのまま保持されました。次の実験では、入力とリソース参照を使ってレポートの内容を管理します。



