Terraformのbackend設定にS3バケットを利用し、APIキーをAWS SSM Parameter Storeに追加した

Terraformを使ってインフラを管理する際、stateファイルの管理とAPIキーの取り扱いをセキュアに行えるように、S3バケットを使ってTerraformの状態ファイルを管理しAPIキーをAWS SSM Parameter Storeに追加しました。

1. S3バケットの作成

まず、Terraformの状態ファイルを保存するためのS3バケットを作成します。AWS CLIを使用して、以下のコマンドを実行しました。

aws s3api create-bucket --bucket terraform-backend-state-for-weather-checker --region ap-northeast-1 --create-bucket-configuration LocationConstraint=ap-northeast-1

コマンドについてメモ

  • --bucket terraform-backend-state-for-weather-checker: S3バケットの名前です。グローバルに一意である必要があります。
  • --region ap-northeast-1: バケットを作成するリージョンを指定します。今回は東京リージョンを選択しています。
  • --create-bucket-configuration LocationConstraint=ap-northeast-1: リージョンが us-east-1 以外の場合、このオプションが必要になるそうです。

2. Terraformのbackend設定を更新

次に、Terraformの設定ファイル(例: main.tf)にbackend設定と必要なプロバイダー設定を追加します。これにより、Terraformの状態ファイルがS3に保存されるようになります。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.62.0"  # 使用するAWSプロバイダーのバージョンを指定
    }
  }

  backend "s3" {
    bucket = "terraform-backend-state-for-weather-checker" # 作成したS3バケット名
    key    = "terraform.tfstate"                          # 状態ファイルの保存先
    region = "ap-northeast-1"                             # S3バケットのリージョン
    encrypt = true                                        # 状態ファイルを暗号化する設定
    profile = "aws_sso"                                   # 使用するAWSプロファイル
  }
}

3. Terraformの初期化

Terraformの初期化を行い、backend設定に基づいて状態ファイルをS3バケットに保存する準備を行います。

terraform init

terraform init を実行することで、S3バックエンドが正しく設定され、状態ファイルがローカルからS3に移行されました。

4. APIキーの保存 - AWS SSM Parameter Storeの利用

次に、APIキーをセキュアに管理するためにAWS CLIを使って以下のコマンドを実行し、AWS SSM Parameter StoreにAPIキーを追加しました。

aws ssm put-parameter \
    --name "/weather-checker/api-key" \
    --value "APIキーの値" \
    --type "SecureString" \
    --region ap-northeast-1

コマンドについてメモ

  • --name "/weather-checker/api-key": Parameter Storeに保存するパラメータの名前です。
  • --value "<APIキーの値>": 保存するAPIキーの値です。実際のAPIキーに置き換えます。
  • --type "SecureString": パラメータを暗号化して保存するための設定です。AWSのデフォルトKMSキーで暗号化されます。
  • --region ap-northeast-1: パラメータを保存するリージョンです。

TerraformではなくAWS CLIAPIキーを管理した理由

TerraformのコードにAPIキーを含めて管理することは、一定のセキュリティリスクが発生しそうだったのでやめておきました。
例えば、環境変数.tfvarsファイルを使ってAPIキーをTerraformに登録すると、意図せずバージョン管理システムにキーが含まれてしまったり、不適切に共有される可能性があります。また、TerraformのコードにAPIキーを埋め込むと、アクセス管理が複雑化し、監査やセキュリティ対策が難しくなるという問題もあります。

これに対して、AWS CLIを使ってAPIキーを直接Parameter Storeに保存する方法は、以下のメリットがあるように感じました。

  • セキュリティが向上: Parameter Storeに保存されたAPIキーはAWSの暗号化機能によって保護されており、Terraformのコードには含まれない。このため、セキュリティリスクが大幅に低減される。

  • アクセス制御の向上: Parameter StoreではIAMポリシーを使用してアクセス権限を細かく管理でき、Terraform内での直接管理よりも安全性が高まる。

  • 監査とログの強化: Parameter StoreへのアクセスはAWS CloudTrailに記録されるため、誰がいつAPIキーにアクセスしたかを追跡でき、セキュリティインシデントの管理が容易になる。

これらの理由から、APIキーをTerraformの中に含めず、既存のParameter Storeに保存された状態を前提にしてインフラを管理するようにしました。

検討したこと: DynamoDBの使用

Terraformの状態ファイルのロック機能を使用するために、DynamoDBを利用する方法も検討しました。まず、以下のコマンドでDynamoDBテーブルを作成しました。

aws dynamodb create-table \
    --table-name terraform-locks-for-weather-checker \
    --attribute-definitions AttributeName=LockID,AttributeType=S \
    --key-schema AttributeName=LockID,KeyType=HASH \
    --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 \
    --region ap-northeast-1
  • --table-name terraform-locks-for-weather-checker: DynamoDBテーブルの名前です。
  • --attribute-definitions--key-schema: テーブルの主キーの設定です。
  • --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1: プロビジョニングされたスループットの設定で、1 RCU(読み込み)と1 WCU(書き込み)の最小値に設定しました。

しかし、DynamoDBの使用料金について整理したところ、最低のプロビジョニング設定でも月に約9ドルのコストが発生するようでした。個人開発ではこのコストが積み重なると負担になるため、コストパフォーマンスを考慮しました。

DynamoDBの削除

個人開発ではDynamoDBを利用するメリットが少ないと判断したため、以下のコマンドでDynamoDBテーブルを削除しました。

aws dynamodb delete-table --table-name terraform-locks-for-weather-checker --region ap-northeast-1

このコマンドを実行することで、不要なDynamoDBのコストを削減し、シンプルな構成に戻すことができました。

まとめ

S3バケットを利用したTerraformのbackend設定と、AWS SSM Parameter Storeを使ったAPIキーの管理、さらにDynamoDBを試してみた上でのコスト分析を行いました。結論として、個人開発においては、DynamoDBを利用するメリットが少ないため、S3だけで十分と判断しました。