📝

AWS SSO設定環境下における、Terraformを使用したS3バケットの作成

に公開

はじめに

IaC(Infrastructure as Code)ツールの一種に、Terraformがあります。
Terraformについて実際に手を動かしながら学ぶために、AWS環境にTerraformでS3バケットを作成してみました。

環境

実施した環境について、簡単に記します。

  • 端末:MacBook Air
  • OS:macOS Sequoia 15.3.2
  • メモリ:16GB
  • Terraform:1.13.4
  • AWS CLI:2.31.27

Terraformの学習が目的であり、すぐに操作可能なAWS環境がIAM Identity CenterのSSO設定下でした。
そのため、マネジメントコンソールから行う諸々のAWSの設定が完了していることを前提としています。

Terraformとは

Terraformは、HashiCorp社が提供しているオープンソースのIaCツールです。
何を作るか(あるべき状態)をHCL(HashiCorp Configuration Language)という、独自のシンプルな言語で記述します。
AWS、Azure、Google Cloudといった主要なパブリッククラウドをはじめ、オンプレミスのVMwareやSaaSなど、様々なプラットフォームに対応しています。
そのため、複数の異なるサービスを横断したインフラの一元管理が可能です。
https://developer.hashicorp.com/terraform

セットアップ

ここでは、macOSのパッケージ管理ツールであるHomebrewを使用します。
※Homebrewのインストール方法はこちらの記事で扱っています。

ターミナルを開き、Homebrewのアップデートを行う以下のコマンドを実行します。

brew update

AWS CLIのインストール

Terraformには、SSOログインを実行する機能がありません。
そこで、AWS CLIを使用して、TerraformがAWSのAPIを操作するために必要な認証情報を取得します。
AWS CLIをインストールします。

brew install awscli

他のインストール方法については、以下のAWS公式のドキュメントを参照してください。
https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html

インストールの確認を行います。
※バージョンが表示されたらOK

aws --version

Terraformのインストール

Terraform公式のドキュメントを参考にインストールを行います。
HashiCorpのHomebrewリポジトリ(Tap)を追加します。

brew tap hashicorp/tap

Terraformをインストールします。

brew install hashicorp/tap/terraform

インストールの確認を行います。
※バージョンが表示されたらOK

terraform --version

S3バケットの作成

AWS CLIの設定

AWS CLIで頻繁に使用する構成設定および認証情報をファイルに保存することができます。

必要な情報を確認します。

  1. ブラウザから「AWS access portal」を開きます。
  2. S3バケットの作成先として指定する「AWSアカウントID」をメモします。
  3. そのアカウントで使用する「ロール名」をメモします。
    例:AdministratorAccess

    AWS access portal画面
  4. 「ロール名」の横の「アクセスキー」をクリックします。
  5. 表示されたモーダルの内容から、「SSOの開始URL」と「SSOリージョン」をメモします。
    例:https://example.awsapps.com/start/#/, ap-northeast-1

    認証情報の確認画面

次に、AWS CLIの設定用ディレクトリを作成します。

mkdir ~/.aws

.awsディレクトリ内に、configファイルを以下の内容で作成します。
< >部分は、先程メモした内容にそれぞれ置き換えてください。

config
[sso-session <任意のセッション名S>]
sso_start_url = <SSOの開始URL>
sso_region = <SSOリージョン>
sso_registration_scopes = sso:account:access

[profile <任意のユーザ名U>]
sso_session = <任意のセッション名S>
sso_account_id = <AWSアカウントID>
sso_role_name = <ロール名R>
region = <SSOリージョン>
output = json

ファイルの詳細については、以下のAWS公式のドキュメントを参照してください。
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html

セッション確立のために、SSO認証を行います。
<your_profilename>は、configファイルで定義した任意のユーザ名Uです。

aws sso login --profile <your-profilename>

コマンドを実行すると、ブラウザ上にAWSのログイン画面が立ち上がります。
コマンド実行後のログイン画面
コマンド実行後のログイン画面

普段通りに認証を行うと以下のような表示となり、データへのアクセス許可を求められます。
Data access request画面
Data access request画面

許可すると、一時的なセッションが確立されます。
Request approved画面
Request approved画面

Terraformの設定

任意の場所に、Terraformのプロジェクトディレクトリを作成します。
※ここでは、ホームディレクトリ内に作成しています。

mkdir ~/tf_test

作成したプロジェクトディレクトリに移動します。

cd ~/tf_test

tf_testディレクトリ内に、main.tfを以下の内容で作成します。

main.tf
# どのクラウドプロバイダを利用するかを定義
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0" # 使用するプロバイダーのバージョンを指定
    }
  }
}

# AWSプロバイダの設定
provider "aws" {
  region = "ap-northeast-1" # 東京リージョン
  profile = "your-profilename" # ~/.aws/configで設定したprofile名
}

# 作成するS3バケットの設定
resource "aws_s3_bucket" "test_bucket_20251118" {
  # S3バケット名は全世界で一意(小文字英数字とハイフンのみ使用可能)
  bucket = "test-terraform-bucket-20251118"

# タグの設定(任意)
#  tags = {
#    Name        = "My first terraform bucket"
#    Environment = "Dev"
#    ManagedBy   = "Terraform"
#  }
}


# 以下、任意
# 1. バージョニングの有効化
# 誤ってオブジェクトを削除・上書きしてしまった場合に復元できる
resource "aws_s3_bucket_versioning" "test_bucket_20251118_versioning" {
  bucket = aws_s3_bucket.test_bucket_20251118.id

  versioning_configuration {
    status = "Enabled"
  }
}

# 2. ブロックパブリックアクセスの設定(推奨)
# 意図しない情報漏洩を防ぐため、原則として全てのパブリックアクセスをブロック
resource "aws_s3_bucket_public_access_block" "test_bucket_20251118_pub" {
  bucket = aws_s3_bucket.test_bucket_20251118.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

今回は学習のために簡素な設定となっていますが、さらに細かな設定が可能です。
詳細については、以下のTerraform公式のドキュメントを参照してください。
https://registry.terraform.io/providers/hashicorp/aws/latest/docs

設定が完了したら、Terraformのプロジェクトディレクトリを初期化します。

terraform init

実行確認と適用

Terraformでは、インフラに変更を適用する前に、どのような変更が加えられるのかを事前に確認することができます。
意図しない変更を防ぎ、安全にインフラを更新するための重要な機能となっています。
以下のコマンドを実行して、変更を確認します。

terraform plan

今回の場合だと、Plan: 3 to add, 0 to change, 0 to destroy.というような結果になるはずです。

確認した内容が問題なければ、実際に変更を適用します。

terraform apply

コマンドを実行すると、以下のように聞かれるので、問題なければyesと入力して実行します。

Plan: 3 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: 

これで、S3バケットが作成できました。

  1. S3バケットの作成先に指定した、AWSアカウントのマネジメントコンソールへアクセスします。
  2. S3 → 汎用バケット からmain.tfで設定した内容のS3バケットが作成されていることが確認できます。
    S3バケットの作成を確認
    S3バケットの作成を確認

【コラム】各ファイルの概要

プロジェクトディレクトリ内のディレクトリやファイルなどを確認します。

ls -al

一連の作業で以下が作成されています。

名前 概要 作成のタイミング
.terraform ダウンロードしたプロバイダや参照されるモジュールが格納されたディレクトリ terraform initの実行後
.terraform.lock.hcl プロバイダやモジュールのバージョン情報を記録したファイル terraform initの実行後
main.tf S3バケット作成用の定義ファイル
terraform.tfstate 管理しているインフラ(リソース)の現在の状態を記録したファイル terraform applyの実行後

【コラム】環境変数

今回、main.tfに直接定義する形式で、AWSプロバイダの設定を行いました。
しかし、有識者によると、regionprofileといった値は実行者ごとに異なる可能性があるため、代わりに環境変数として指定することが多いみたいです。
環境変数として指定する方法として、以下の2つがあります。

  • Terraformの変数(variables)を使用する
  • AWS CLIの環境変数を直接使用する

ここでは、AWS CLIの環境変数を直接使用する方法について、説明します。

  1. main.tfのAWSプロバイダの設定において、regionprofileの行をコメントアウト(削除)します。
  2. 環境変数をexportで設定してからterraform planterraform applyを実行するか、環境変数を指定しつつterraform planterraform applyを実行するのか、のどちらかで行うことができます。
exportで設定して順番に実行
export AWS_REGION=ap-northeast-1
export AWS_PROFILE=your-profilename
terraform plan
terraform apply
1回で実行
AWS_REGION=ap-northeast-1 AWS_PROFILE=your-profilename terraform plan
AWS_REGION=ap-northeast-1 AWS_PROFILE=your-profilename terraform apply

S3バケットの削除

片付け

作成したリソースを削除します。

terraform destroy

コマンドを実行すると、以下のように聞かれるので、問題なければyesと入力して実行します。

Plan: 0 to add, 0 to change, 3 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: 

今回の場合だと、Destroy complete! Resources: 3 destroyed.というような結果になるはずです。

これで、S3バケットを削除できました。

  1. S3バケットの作成先に指定した、AWSアカウントのマネジメントコンソールへアクセスします。
  2. S3 → 汎用バケット からmain.tfで設定した内容のS3バケットが削除されていることが確認できます。
    S3バケットの削除を確認
    S3バケットの削除を確認

【コラム】S3バケットの削除を確認する別の方法

AWS CloudTrailからでも、S3バケットの削除を確認することができます。
具体的には、DeleteBucketを確認します。
S3バケットを削除したイベント
S3バケットを削除したイベント

【コラム】S3バケットの削除に失敗

S3バケット内にオブジェクトがあるとエラーとなり、削除に失敗することがあります。
試しに再度TerraformでS3バケットを作成し、オブジェクトをアップロードしてみました。
terraform destroyを実行すると、以下のような結果となりました。

Error: deleting S3 Bucket (test-terraform-bucket-20251118): operation
error S3: DeleteBucket, https response error StatusCode: 409, RequestID: 
  (中略)
api error BucketNotEmpty: The bucket you tried to delete is not empty. 
You must delete all versions in the bucket.

これは、S3バケットが間違って削除されることに伴い、S3バケット内のオブジェクトが消失することを防ぐための、安全側に倒した挙動といえます。
ただし、注意しなければならないことが、S3バケットの削除に失敗しても、ブロックパブリックアクセスの設定は削除されることがあるということです。
ブロックパブリックアクセスの設定が削除されたS3バケットは、インターネットへの公開が許可された状態となります。
そのため、バケットポリシーやACLの設定(誰に公開するか)次第で、オブジェクトが全世界に公開されてしまいます。

このエラーを解消し、S3バケットを削除したい場合は、

  • AWS CLIやマネジメントコンソールなどから、オブジェクトを削除する
  • main.tfのS3バケットの設定にforce_destroy = trueを追加し、オブジェクトの有無に関係なく強制削除されるようにする

といった対応が考えられます。
詳細な対応策については以下の記事がわかりやすかったため、参照してみてください。
https://dev.classmethod.jp/articles/terraform-s3-public-access-block-tips/

まとめ

今回は、Terraformを使用してAWS環境にS3バケットを作成しました。
TerraformはIaCツールであるといった程度の知識でしたが、実際に手を動かしながら学んでみることで理解が進みました。
S3バケットを作成するのは、Terraformの基本を知るための最初のステップとして有効だと思います。
Terraformの学習はこれから、という方は参考にしてみてください。

参考文献

株式会社サイバーセキュリティクラウド テックブログ

Discussion