🐷

TerraformのbackendをOCI Object Storageに設定する方法

2025/02/08に公開

はじめに

TerraformのbackendをOCI Object Storageに設定する方法を調べてみました。
認証情報作成とTerraform backendの記述方法を記載します。

検証環境

$ terraform -v
Terraform v1.10.5
on linux_amd64

実装

tfstate保存用オブジェクトストレージ作成

ストレージ > オブジェクト・ストレージとアーカイブ・ストレージ > バケット > バケットの作成

認証情報作成

backendの設定には顧客秘密キーが必要です。
まず、任意のユーザーに対して顧客秘密キーを作成します。

GUIから作成する場合

アイデンティティ・セキュリティ > ドメイン > ユーザー > 顧客秘密キー > 秘密キーの生成

上記順序で進んでいき秘密キーを作成します。
するとキーが生成され、パスワードが表示されるので控えておきます。
このパスワードは画面を閉じた時点で確認する方法がなくなりますので注意してください。

続いて、作成した顧客秘密キーのidを控えます。

CLIから作成する場合

$ export DISPLAY_NAME=<顧客秘密キーの名前、重複可>
$ export USER_ID=<顧客秘密キーを作成するユーザーのocid>

$ oci iam customer-secret-key create \
  --display-name $DISPLAY_NAME \
  --user-id $USER_ID

上記コマンドが成功すると以下のようなJSONが返ってきます。
必要な値を漏洩しないように気を付けて控えておきます。

{
  "data": {
    "display-name": "example",
    "id": "xxxxxxxxxxxxxxxxxxxx", #### ここのidが顧客秘密キーのid,控えます。
    "inactive-status": null,
    "key": "xxxxxxxxxxxxxxxxxxxx", #### ここのkeyが顧客秘密キーのパスワード,控えます。
    "lifecycle-state": "ACTIVE",
    "time-created": "2025-01-28T07:27:29.905000+00:00",
    "time-expires": null,
    "user-id": "xxxxxxxxxxxxxxxxxxxx"
  },
  "etag": "xxxxxxxxxxxxxxxxxxxx"
}

後述しますが、控えておいた2つの値はそれぞれ

  • 顧客秘密キーのパスワード -> aws_secret_access_key
  • 顧客秘密キーのid -> aws_access_key_id

の値としてTerraformのbackend設定に使用します。

グループ・ポリシー作成

顧客秘密キーを作成したユーザーはObject Storageのバケットに対して操作できるようにグループとポリシーを作成する必要があります。

グループ作成

アイデンティティ・セキュリティ > アイデンティティ・ドメイン > グループ > グループの作成
上記順序で進んでいきグループを作成します。

作成したグループに顧客秘密キーを作成したユーザーを追加します。

ポリシー作成

続いて先ほど作成したグループへポリシーを付与してユーザーがその権限を使用できるようにします。

アイデンティティ・ドメイン > アイデンティティ > ポリシー > ポリシーの作成
上記順序で進んでいきポリシーを作成します。

記述するポリシーは以下を適宜変更してください。(もう少しポリシーは絞れそうですね)

### 記述例
Allow service objectstorage-<Region Identifier> to manage object-family in tenancy

私の場合は以下のように記述しました。

Allow service objectstorage-ap-tokyo-1 to manage object-family in tenancy

Terraform backend記述

では実際にTerraformのbackend設定を記述していきます。
その前に最初に作成した顧客秘密キーの情報を設定ファイルへ記述します。

顧客秘密キーのファイル記述

AWSの認証情報ファイルと同じように記述します。

$ cat ~/.aws/credentials
[default]
aws_access_key_id=<顧客秘密キーのid>
aws_secret_access_key=<顧客秘密キーのパスワード>

他の場所に設定ファイルを置きたい場合はterraformの記述で変更することができます。(shared_credentials_fileプロパティ)
詳しくは後述いたします。

この値は環境変数に設定することで使用することもできます。

$ export AWS_ACCESS_KEY_ID=<顧客秘密キーのid>
$ export AWS_SECRET_ACCESS_KEY=<顧客秘密キーのパスワード>

Terraform backend記述

Terraformのbackend設定は以下のように記述します。

# (Terraform version >= 1.6.4)
terraform {
  backend "s3" {
    bucket                      = "<先ほど作成したバケット名>"
    region                      = "<先ほど作成したバケットのリージョン>"
    key                         = "terraform.tfstate"
    skip_region_validation      = true
    skip_credentials_validation = true
    skip_requesting_account_id  = true
    use_path_style              = true
    skip_s3_checksum            = true
    skip_metadata_api_check     = true
    endpoints = {
      s3 = "https://<テナンシのネームスペース>.compat.objectstorage.<ストレージのリージョン>.oraclecloud.com"
    }

    ### もし、AWSの認証情報ファイルを別の場所にした場合は以下のように記述します。
    shared_credentials_file     = "<AWSの認証情報ファイルのパス>"

    ### もし、AWSの認証情報ファイルのプロファイル名を変更している場合は以下のように記述します。
    profile                     = "<AWSの認証情報ファイルのプロファイル名>"
  }
}

ここまでで正しく設定に成功していれば terraform init が通るはずです。

$ terraform init
Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

実際にストレージにtfstateが保存されているか確認してみます。

無事OCIオブジェクトストレージへtfstateファイルを保存することに成功しました。

おまけ: backend.tfの値をリポジトリ管理させたくないとき

悲しいことにbackendブロックでは変数を使用することができません。
そのためterraform.tfvarsファイルへマスクしたい値を記述してリポジトリに情報を保存しないといった構成が取れません。
そのため、terraform init実行時に -backend-config を使用する方法をとります。
そうすることでマスクしたい値を記述した設定ファイルを.gitignoreなどでリポジトリ管理から除外することができます。

早速試してみましょう。

$ cat config.tfbackend ### -backend-config で指定するファイル、名前は任意です。
bucket                      = "xxxxxxxxx"
region                      = "xxxxxxxxx"
key                         = "xxxxxxxxx"
profile                     = "xxxxxxxxx"
shared_credentials_file     = "xxxxxxxxx"
endpoints = {
    s3 = "xxxxxxxxx"
}

$ cat backend.tf
terraform {
  backend "s3" {
    skip_region_validation      = true
    skip_credentials_validation = true
    skip_requesting_account_id  = true
    skip_metadata_api_check     = true
    skip_s3_checksum            = true
    use_path_style              = true
  }
}

上記のファイル構成で terraform init -backend-file を試します。

$ terraform init -backend-config=config.tfbackend
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/oci from the dependency lock file
- Using previously-installed hashicorp/oci v6.23.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

これでリポジトリ管理から除外する準備が整いました。
.gitignoreで指定するなりしてファイルを除外して完了となります。

おわりに

S3 APIを使用した少々トリッキーな実装だなと感じました。
OCIはまだまだ情報が少ないので沢山発信していければなと思います。

参考

Discussion