aws terraform

Terraform バックエンドにTerraformCloudを設定する

terraformはインフラの状態情報を持っておりデフォルトの場合、ローカル環境に terraform.tfstate というファイル名で保存されます。ただこのままであると、

  • 機密データの適切な管理がしづらい。
    tfstateファイルにMySQLの管理パスワードやGitHubのToken などの情報が平文で乗ってしまう。
  • 複数メンバー間での状態情報の共有がしづらい。
    例えばgitで管理しようとした場合、terraform実行の前にわざわざpullしなければならない。また機密データをコミットするハメになる。

などの問題が生じます。


そこで状態情報をローカルからリモート管理へすることで排他ロックを含む共有が可能となり、セキュリティについては以下のポイントで向上できます。(terraformの考え方としては状態情報自体が機密データ)

  • 状態情報自体にアクセス制限をかけることで情報を守ることができる。
  • 履歴や監査ログからアクティビティを追跡できる。
  • ディスクに保存されている情報を暗号化できる。


リモート管理にはS3やGCSなど複数種類の方法が用意されています。

その一つであるTerraformCloudは、2019年9月に5名まで無料になり少人数チームでの状態管理であれば、その無料枠内で利用できます。(無料になるまではAWSの状態管理はS3 & DynamoDB で管理が普通だったんでしょうか。ググる限り結構大変そう。。)

では今回は標準のローカル管理している状態から、TerraformCloudでのリモート管理へ移行する流れでやってみます。

スポンサーリンク

手順

ローカル管理

例としてEC2を1台構築する設定ファイルを準備します。

% cat main.tf 
provider "aws" {
  region = "ap-northeast-1"
  profile = "default"
}

resource "aws_instance" "example" {
  ami           = "ami-0ce107ae7af2e92b5"
  instance_type = "t2.micro"
}
% 


初期化します。必要なプラグインがダウンロードされます。

% terraform init

Initializing the backend...

...

% 


実際に適用します。AWS上にEC2が1台構築されます。

% terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
...

Plan: 1 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

...

% 


ローカルに状態情報が記載された terraform.tfstate が作成されます。

% ls
main.tf			terraform.tfstate
% 
% cat terraform.tfstate 
{
  "version": 4,
  "terraform_version": "0.13.3",
  "serial": 1,
  "lineage": "xxxx-xxx-yyyyy-yyyyy-zzzzzz",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",

...

リモート管理

では上記で作成したローカルにある状態情報をリモート管理へ移行します。

TerraformCloud アカウント登録

Terraform Cloud

へアクセスし、メールアドレス、パスワードなどを登録します。
登録したメールアドレスに確認用リンクが来るので、そのリンクをクリックします。

組織作成

大本となる組織を作成します。

組織名は既に誰かに使用されているとエラーとなります。S3のバケット名のように一意な名前で作成してください。

ワークスペース作成

ワークスペース(tfstateを管理する場所)を作成します。

CLI-driven workflow を選択し、ワークスペース名を入力します。


Settingsタブ -> Execution Mode で Local を選択します。
デフォルトだとRemote(terraformクラウドでの動作)になっており、ローカル実行時にエラーとなってしまいます。

APIトークン生成

一旦ターミナルへ戻り terraform login コマンドを実行すると再度ブラウザへ飛ばされます。
ブラウザでAPIトークンを生成し、それをターミナルに貼り付けてローカルへ保存します。

% terraform login

...

Do you want to proceed?
  Only 'yes' will be accepted to confirm.

  Enter a value: yes          -> yesを入力します。

...


Token for app.terraform.io:
  Enter a value:            -> ブラウザで作成したAPIトークンを貼り付けます。

...

Success! Terraform has obtained and saved an API token.

...
% 

リモートへ移行

設定ファイルに terraform ブロックを追加します。

% cat main.tf 
terraform {            -> このブロックを追加します。
  backend "remote" {
    organization = "test-org"

    workspaces {
      name = "test-work"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
  profile = "default"
}

resource "aws_instance" "example" {
  ami           = "ami-0ce107ae7af2e92b5"
  instance_type = "t2.micro"
}
% 


初期化をすると現在ローカルにある状態情報をリモートへ保存するかどうか聞かれるのでyesを入力します。

% terraform init

Initializing the backend...
Acquiring state lock. This may take a few moments...
Do you want to copy existing state to the new backend?
  Pre-existing state was found while migrating the previous "local" backend to the
  newly configured "remote" backend. No existing state was found in the newly
  configured "remote" backend. Do you want to copy this state to the new "remote"
  backend? Enter "yes" to copy and "no" to start with an empty state.

  Enter a value: yes       -> yesを入力します。


Successfully configured the backend "remote"! Terraform will automatically
use this backend unless the backend configuration changes.

...

% 


ブラウザで States タブ を選択すると状態情報が保存されていることが確認できます。

以降apply のたびに履歴が増えていきます。履歴をそれぞれクリックすると状態の詳細、および前回との差分を確認できます。


なおローカルの状態情報は元々あった terraform.tfstate は空になり、隠しディレクトリ配下のterraform.tfstateへリモートの情報が記載されています。

% ls  
main.tf				terraform.tfstate		terraform.tfstate.backup
% 
% cat terraform.tfstate
% cat .terraform/terraform.tfstate 
{
    "version": 3,
    "serial": 1,
    "lineage": "xxxxxx-xxxxx-xx-xx-xxxxxxx",
    "backend": {
        "type": "remote",
        "config": {

補足

TerraformCloudアカウント 2段階認証

Terraform CloudはAWSアカウントと同様、QRコードやSMSを使用した2段階認証が利用できます。ぜひ設定しましょう。

画面右上部のユーザーアイコン -> User Settings -> Two Factor Authentication より設定できます。

Credential 手動設定

terraform login でAPIトークンを保存するとホームディレクトリの/.terraform.d配下に自動で保存されます。

% ls ~/.terraform.d
checkpoint_cache		checkpoint_signature		credentials.tfrc.json.bk
% cat ~/.terraform.d/credentials.tfrc.json.bk 
{
  "credentials": {
    "app.terraform.io": {
      "token": "xxxxxxxx123456789xxxxxxxx123456789xxxxxxxx123456789"
    }
  }
}
%


手動で設定する場合はCLI Configuration File の terraformrc に記載しても動作します。

% cat .terraformrc 
credentials "app.terraform.io" {
  token = "xxxxxxxx123456789xxxxxxxx123456789xxxxxxxx123456789"
}
%

バックエンドの設定

手順中の説明では main.tf に直接Terraform Cloud の組織名やワークスペースを記載しました。

これらの情報をGitHubなどにコミットしたくない!場合は、以下のようにコミット対象外のファイルにバックエンドの情報を記載して、初期化時にファイルを引数指定して渡せます。

% cat backend.hcl                   -> backend.hcl はコミットしない
organization = "test-org"
workspaces { name = "test-work" }

% 
% terraform init --backend-config=backend.hcl

参考

ヾ(●>д<)ノThank You

Terraform Cloud and Terraform Enterprise
Sensitive Data in State
CLI Configuration File – Credentials
Terraformの「ここはvariable使えないのか…」となった所

タイトルとURLをコピーしました