初めての AWS リソースを作成して削除する

AWSBeginner
オンラインで実践に進む

はじめに

チームには、レポートを保存するための非公開ストレージが必要です。この実験では、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 の設定が状態の対応付けを通じて 1 つの S3 バケットを管理し、別の参照用バケットは保持されます。

レポート用バケットを作成する

このステップでは、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 オブジェクトには手を加えないでください。

作成後の AWS View:Terraform が管理する空のレポート用バケットが、変更されていないチームの参照用バケットの隣に表示されています。

コマンドを完了したら 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 View:Terraform が管理するバケットはなくなり、別のチームの参照用レポートは残っています。

まとめ

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