※ 本記事は、Ed Shnekendorfによる”Solve State Locking and Token-Based Authentication Challenges with the new OCI Backend for Terraform“を翻訳したものです。

2025年6月27日


背景

HashiCorp社によって開発されたオープンソースのInfrastructure as Code (IaC)ツールであるTerraformは、Oracle Cloud Infrastructure (OCI)で幅広く使用され、クラウド・リソースのプロビジョニングと管理を自動化します。これにより、ユーザーはインフラストラクチャ構成を宣言言語で定義できるため、コンピュート・インスタンス、ネットワーキング・コンポーネント、ストレージなどのOCIリソースの一貫した反復可能なデプロイメントが可能になります。

Terraformのユーザーの一般的な懸念事項は、マルチユーザー環境でTerraformを使用する場合の状態の管理です。Terraformは、クラウド・デプロイメントのローカル表現をterraform.tfstateファイルに保持し、この状態に対する作成、更新または削除リクエストをリコンサイルします。独自の異なるクライアント環境から作業している複数のユーザーは、相互の変更を上書きすることなく、クラウド環境のメンテナンスでコラボレーションできる必要があります。

この懸念に対処するために、HashiCorpは、リモート状態管理の概念をTerraformに追加しました。これにより、状態ファイルをクラウド・サービス・プロバイダ(CSP)のオブジェクト・ストレージ内にリモートで格納し、すべてのコラボレータからアクセスできます。

OCIは、この機能をいくつかの方法でサポートしています。第1に、OCIでは、S3互換バックエンドを介したTerraformのバックエンドとしてのOCI Object Storageの使用が長年にわたってサポートされています。

次に、OCIは、Resource Managerと呼ばれるフルマネージドで無料のTerraform-as-a-Serviceツールを提供します。このツールは、マルチユーザーの状態をリモートで管理しながら、ドリフト検出、環境イントロスペクション、アイデンティティとアクセス(IAM)統合などの他の利点も提供します。Resource Managerは完全なソリューションを提供しますが、多くのマルチクラウドのお客様は、CSPごとにIaCコードを更新するのではなく、ネイティブなTerraform APIとツールを使用することを好みます。

 

ロックと長期間のキー・チャレンジ

S3互換バックエンドはリモート状態の問題を解決しますが、2つのクライアントが同時に状態を書き込む可能性がある競合状態をネイティブで処理しないため、リモート状態ファイルが破損したり、非決定的な終了状態になります。HashiCorp社は、状態ロックの概念を導入し、多くのCSPが、ロックを処理するためにデータベース(CosmosDBまたはDynamoDB)を利用したソリューションを作成しました。ただし、S3互換バックエンドは、何年もの間OCIの唯一のオプションでしたが、ステートレス実装であり、状態ロックは提供されません。

また、OCI Terraformプロバイダは認証に短期間のトークンの使用をサポートしていますが、S3互換バックエンドでは、認証に永続的で長期間のキーが必要です。セキュリティ・ポリシーと手順により、従業員のラップトップへの永続的なキーの配布が禁止されているOCIのお客様は、特にキーのローテーションや失効のための自動化されたソリューションがないと、バックエンドのこの側面に特に問題があることがわかりました。

 

新しいOCIネイティブ・バックエンドへようこそ

OCIは、OCIネイティブ・バックエンドであるHashiCorp社の友人と協力して、S3互換バックエンドへの依存関係を削除し、状態ロックと長期間のキー・チャレンジにネイティブに対処することを嬉しく思います。新しいバックエンドは、Terraformのバージョン1.12以降でサポートされており、新しいバックエンドのドキュメントはここにあります。

 

状態ロック

クラウド・データベースを使用してロックを管理するのではなく、バックエンドは、意図しない競合状態を防止する条件付き操作を有効にすることで、OCIオブジェクト・ストレージによるオプティミスティックな同時実行性制御のサポートを利用します。

クライアントがTerraformプラン/適用/破棄操作を開始すると、If-None-Match (* HTTPヘッダーはバックエンドによって使用され、ロック・ファイルをリモート状態バケットに配置しながら、first-writer-winsを適用)リクエストは、ロック・オブジェクトがバケットにすでに存在しない場合にのみ成功し、後続のコンカレント要求が412 Precondition Failedで失敗します(ロックがすでに存在する場合)。

このロジックにより、操作のアトミック性が保証され、別の処理中のクライアントが操作を実行しようとすると、「Error acquiring the state lock (状態ロックの取得中にエラーが発生しました)」というメッセージが表示され、再試行するよう求められます。

 

トークン・ベース認証

OCIバックエンドは、OCI Terraformプロバイダでサポートされているものと同じ認証プロトコルのすべてをサポートします。次のものがあります:

  • APIキー
  • インスタンス・プリンシパル
  • リソース・プリンシパル
  • OKEワークロード・アイデンティティ
  • セキュリティ・トークン

つまり、お客様は、任意の認証方法を使用して、OCI Terraform操作全体でセキュリティ・アプローチを標準化できます。

トークン認証を全面的に行おうとしている方は、現在、OCIのトークンベース認証を活用して、ユーザー・アクセス用の短期間のセッション・トークンを作成できます。近い将来、OCI Token Exchange Serviceの今後のリリースでさらに可能性が広がります。

 

OCIバックエンドの操作

Terraformのバージョン1.12 (以降)をインストールし、ローカルのTerraformディレクトリに「terraform init」コマンドを発行してバックエンドを初期化したことを確認します。さらに、OCIコマンドライン・インタフェース(CLI)の最新バージョンもインストールする必要があります。

Terraformプロジェクトのリモート・バックエンドを有効にするには、backend.tfファイルを追加します(または、ディレクトリ内の任意の.tfファイルに次のコード・ブロックを追加します)。

terraform {
  backend "oci" {
    bucket    = "tf-remote-state"
    namespace = "foobar"
    }
}

ネームスペースはOCIテナンシのオブジェクト・ストレージ・ネームスペースに対応している必要があります。バケット名は、この目的のためにすでに作成した新しいバケットとその名前に対応している必要があります。作業ディレクトリにterraform initコマンドを発行して、バックエンドを初期化できるようになりました。ローカルterraform.stateがある場合、または同じバケットに(S3互換バックエンドから)以前のリモート状態が構成されている場合は、必ずinitコマンドに-migrate-stateフラグを指定してください。

$> terraform init

Initializing the backend...

Successfully configured the backend "oci"! Terraform will automatically 
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Finding latest version of hashicorp/oci...
- Installing hashicorp/oci v6.36.0...
- Installed hashicorp/oci v6.36.0 (signed by HashiCorp)

Terraform has been successfully initialized!

これで、Terraformのplan/create/destroyコマンドを記述できるようになりました。terraform.tfstateファイルがオブジェクト・ストレージ・バケット内でマスターされていることがわかります。

object list

操作の実行中に、同じバケットに存在するロック・ファイルも表示され、そのロック・ファイルが存在すると同時操作が妨げられます。操作が完了または終了すると、ロック・ファイルがバケットから削除されます。

bucket with state file

操作の実行中に別のユーザーがTerraform操作を実行しようとすると、次のエラーが表示され、バックオフして再試行する必要があります。

$> terraform apply
╷
│ Error: Error acquiring the state lock
│
│ Error message: Error returned by ObjectStorage Service. Http Status Code: 412. Error Code: IfNoneMatchFailed. Opc
│ request id: iad-1:pi_B30zba7upYMZiKZw-fz3Zhj6Y5ZcxSX3YoPqKlzWW0Pr66wnuJFzsyc6MAqQC. 
| Message: The If-None-Match header is '*' but there is an existing entity
│ Operation Name: PutObject
│ Timestamp: 2025-04-25 15:44:35 +0000 GMT
│ Client Version: Oracle-GoSDK/65.89.1
│ Request Endpoint: PUT

トークン・ベース認証を実装する場合は、バックエンド・ブロックおよびプロバイダ・ブロックを次のように変更する必要があります:

provider "oci" {
  auth = "SecurityToken"
  config_file_profile = "tf"
  region = "us-ashburn-1"
}

terraform {
  backend "oci" {
    bucket    = "tf-remote-state"
    namespace = "foobar"
    auth = "SecurityToken"
    config_file_profile = "tf"
    region = "us-ashburn-1"
    }
}

bucket属性とnamespace属性は変更されませんが、プロバイダ・ブロックとバックエンド・ブロックの両方で3つの新しい属性が必要であることに注意してください:

  • auth:  これはSecurityTokenである必要があります
  • config_file_profile: SecurityTokenプロファイルに対応するOCI構成ファイル(~/.oci/config)のキー。ここで、CLI経由で認証するときに使用される一意の名前を選択します。
  • region:  APIをコールしており、オブジェクト・ストレージ・バケットが作成されているOCIリージョンの指標

Terraformと対話する前に、まずOCIで認証し、存続期間の短いトークンを受け取る必要があります。Terraform構成と一致するregionおよびconfig_file_profileを使用してoci session authenticateコマンドを発行すると、ブラウザにリダイレクトされ、認証が許可され、セッション構成内に短期間のトークンが配置された状態でシェルに戻ります。

$> oci session authenticate --region us-ashburn-1 --session-expiration-in-minutes 60 --profile-name tf

    Please switch to newly opened browser window to log in! You can also open the following URL in a web browser window to continue:
     https://login.us-ashburn-1.oraclecloud.com/v1/oauth2/authorize?action=login&client_id=iaas_console&response_type=token+id_token&nonce=[redacted]&scope=openid&public_key=[redacted]]&redirect_uri=http%3A%2F%2Flocalhost%3A8181
    Completed browser authentication process!

Config written to: /Users/eshneken/.oci/config

    Try out your newly created session credentials with the following example command:

    oci iam region list --config-file /Users/eshneken/.oci/config --profile tf --auth security_token

これで、Terraformのplan/apply/destroy操作を実行でき、存続期間が長いAPIキーをローカル・コンピュータに配置する必要はありません。

 

まとめ

リモートのTerraform状態を同時実行性とセキュリティに配慮した方法で管理するマルチクラウド・フレンドリな方法を待っていた場合は、待機は終了しました。Terraformの最新バージョンを入手し、バックエンドのドキュメントを確認して、今すぐネイティブに移行しましょう。