こんにちは id:dhigashi です。
Terraform では管理対象のインフラを管理するために、デフォルトではローカルに terraform.tfstate
というファイルを作成し現在の状態を保存しています。
一人で開発している時には特に問題はありませんが、複数人で開発する場合では最新の状態を共有する必要があるなど管理が困難になります。
この問題を解決するため Terraform では Backend という機能により、リモートに状態を保存する事ができます。
現在 Terraform では様々な Backend Types がサポートされています。
今回はこれらの内、HTTP
と S3
Type を利用し Object Storage を Backend として利用してみたいと思います。
Using the Object Store for Terraform State Files
事前準備
本記事は、Terraform が利用できる事を前提としています。
Terraform の導入がまだの場合は、以下の記事をご覧ください。
また、今回はテストの為に以下の単純な VCN を作成しています。
構成ファイルは以下のリポジトリから参照してください。
HTTP backend
HTTP backend は GET による状態の取得、POST による状態の更新など、REST を利用し状態を管理します。
この時 Object Storage に対して資格情報無しで操作を行うために、事前承認リクエスト を利用します。
事前承認リクエストについては、以下の記事をご覧ください。
terraform.tfstate
オブジェクトに対し、読み書きができる事前承認リクエストを作成します。
Backend のタイプに http
を指定し、address
に 発行されたリクエスト URL を update_method
に PUT
を設定します。
terraform { backend "http" { address = "https://objectstorage.us-phoenix-1.oraclecloud.com/<my-access-uri>/example-terraform-state/o/terraform.tfstate" update_method = "PUT" } }
Terraform の初期化と構成の適用を行います。
$ terraform init 略 Terraform has been successfully initialized!
$ terraform apply An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: + oci_core_default_route_table.DefaultRT 略 + oci_core_internet_gateway.ExampleIG display_name: "Example Internet Gateway" vcn_id: "${oci_core_vcn.ExampleVCN.id}" 略 + oci_core_security_list.AllowSSH display_name: "Allow SSH" vcn_id: "${oci_core_vcn.ExampleVCN.id}" 略 + oci_core_subnet.ExamplePublicSubnet availability_domain: "dArW:PHX-AD-1" cidr_block: "172.16.1.0/24" display_name: "Example Public Subnet" 略 + oci_core_vcn.ExampleVCN cidr_block: "172.16.0.0/16" display_name: "Example VCN" 略 Plan: 5 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: yes oci_core_vcn.ExampleVCN: Creating... 略 Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
リソースの作成が成功し、Web コンソールからも作成した VCN を確認する事ができます。
また、Object Storage には terraform.tfstate
ファイルが作成されている事が確認できます。
以上のように 事前承認リクエスト と HTTP backend により Object Storage を Backend として利用する事ができました。
但し、事前承認リクエスト はリクエスト URL が有効な限り、URL にアクセスできれば誰でも操作を行う事ができます。
tfstate ファイルには機密情報が含まれる場合もあるため、事前承認リクエスト を利用できるか慎重に検討する必要があります。
S3 backend
続いて S3 backend
で状態を保存します。
S3 backend
は Object Storage の S3 互換 API を利用し状態を管理します。
まず Amazon S3 Compatibility API Key (S3 互換 API キー) を作成します。
Object Storage に対して操作権限をもったユーザーで Secret Key を生成します。
適当な名前を指定し、生成された Secret Key と Access Key を控えておきます。
資格情報 を ~/.aws/credentials
へ格納します。
$ cat ~/.aws/credentials [profile_name] aws_access_key_id=<access_key> aws_secret_access_key=<secret_key>
さきほど http
を指定した Backend を s3
に変更し、各パラメータを設定します。
profile
には credentials
に格納した時に指定したプロファイル名を指定します。
terraform { backend "s3" { bucket = "<bucket_name>" key = "terraform.tfstate" profile = "<profile_name>" # ~/.aws/credentials region = "us-phoenix-1" endpoint = "https://<namespace>.compat.objectstorage.us-phoenix-1.oraclecloud.com" skip_region_validation = true skip_credentials_validation = true skip_requesting_account_id = true skip_get_ec2_platforms = true skip_metadata_api_check = true force_path_style = true } }
Backend を変更したので、再度 terraform init
コマンドを実行します。
$ terraform init Initializing the backend... Backend configuration changed! Terraform has detected that the configuration specified for the backend has changed. Terraform will now check for existing state in the backends. Terraform detected that the backend type changed from "http" to "s3". Successfully configured the backend "s3"! Terraform will automatically use this backend unless the backend configuration changes. 略 Terraform has been successfully initialized!
Backend の設定の変更が完了したので、再度 terraform apply
コマンドにより構成を適用してみます。
$ terraform apply 略 Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
構成に変更が無く、何も実行されませんでした。
Backend を変更しても同じ tfstate ファイルを指定し参照している為、構成の状態を引き継いでいる事が確認できました。
まとめ
Terraform の HTTP
と S3
Backend を利用し Object Storage に構成の状態を保存できる事が確認できました。
また、Terraform には State Lock という機能により、複数人が同時に構成を変更できないようロックする事ができます。
S3 backend
では DynamoDB
を用いてロック機能を利用する事ができますが、今回ご紹介した方法では実現できていないため、 本番で利用するには更に工夫が必要かもしれません。