Terraformの基礎(Terraform学習備忘録 #1)

Terraformの基礎(Terraform学習備忘録 #1)

Terraformを学習内容を備忘録として残します。versionはv1.6です。

Terraformとは

Terraformは、HashiCorpによって作成されたオープンソースの「Infrastructure as Code」ツールです。このツールを使用すると、開発者はHCL(HashiCorp構成言語)と呼ばれる高レベルの構成言語を使用して、アプリケーションを実行するために必要な、クラウドまたはオンプレミスのインフラストラクチャーの「最終状態」を記述できます。

Terraformは以下のようなことが可能です。

  • インフラストラクチャーのプロビジョニング:Terraformは単純な構文を使用し、複数のクラウドとオンプレミスのデータセンターにインフラストラクチャーをプロビジョニングできます。
  • インフラストラクチャーの再プロビジョニング:構成の変更に応じてインフラストラクチャーを安全かつ効率的に再プロビジョニングできます。
  • Infrastructure as Code(IaC):開発者はインフラストラクチャーをコード化でき、プロビジョニングの自動化、高速化、再現が可能となります。


また、Terraformは以下の特徴も持っています。

  • オープンソース:Terraformは、プラットフォームへのプラグインを構築する貢献者たちから成る大規模なコミュニティーによって支えられています。
  • プラットフォームにとらわれない:どのクラウド・サービスのプロバイダーでも使用できます。
  • 不変インフラストラクチャー:Terraformは、不変インフラストラクチャーをプロビジョニングします。

Console

terraform console コマンドは、式の評価と実験のための対話型コマンドラインコンソールを提供します。コンフィギュレーションで使用する前に補間式をテストしたり、現在ステートに保存されている値を操作したりするために使用できます。現在の状態が空であるか、まだ作成されていない場合、コンソールを使用して式の構文と組み込み関数を試すことができます。コンソールはステートをロックし、ステートを変更する他のアクションを実行中はコンソールを使用できません。

コンソールを閉じるには、exitコマンドを入力するか、Control-CまたはControl-Dを押します。

$ terraform console
>

terraform コンソールコマンドは、改行で区切られたコマンドをパイプラインで渡すことで、 非対話型スクリプトで使用することができます。エラーが発生しない限り、最終コマンドの出力のみが表示されます。

$ echo 'split(",", "foo,bar,baz")' | terraform console
tolist([
  "foo",
  "bar",
  "baz",
])

HCLの構文

Terraformは、.tf で終わるファイルを読み取ります。

変数

Terraformでは変数を扱うことができます。変数には型があり、type で定義します。

string

# main.tf
variable "myvar" {
  type = string
  default = "Hello Terraform"
}
$ terraform console
> var.myvar
"Hello Terraform"
> "${var.myvar}"
"Hello Terraform"

map

map型は各々が文字列ラベルで識別される値のコレクションです。

キーワードmapはmap(any)の省略形であり、すべての要素が同じ型である限り、どのような要素型でも受け入れることができます。

マップは中括弧({})とコロン(:)、または等号(=)で作ることができます: { "foo":「bar", "bar":"bar": "bar", "bar": "baz" } あるいは { foo = "bar", bar = "baz" } となります。ただし、キーが数字で始まる場合は引用符が必要です。1行マップの場合、キーと値のペアの間にはカンマが必要です。複数行のマップでは、キーと値のペアの間は改行で十分です。

出力値の tomap 関数は引数をマップ値に変換していることを意味しています。

また、鍵括弧([])を使うことで値だけを取り出すこともできます。

# main.tf
variable "mymap" {
  type = map(string)
  default = {
    mykey = "my value"
  }
}
$ terraform console
> var.mymap
tomap({
  "mykey" = "my value"
})
> var.mymap["mykey"]
"my value"

list

ゼロから始まる連続した整数によって識別される一連の値です。配列と同義です。

キーワードlistはlist(any)の省略形であり、すべての要素が同じ型である限り、どのような要素型でも受け付けます。list(number), list(string) のような形で指定することもできます。

# main.tf
variable "mylist" {
  type = list(number)
  default = [1, 2, 3]
}
$ terraform console
> var.mylist
tolist([
  1,
  2,
  3,
])
> var.mylist[0]
1
> element(var.mylist, 1)
2
> slice(var.mylist, 0, 2)
tolist([
  1,
  2,
])

element は関数で、list の要素を扱うことができます。

element(list, index)

slice も関数で、list 内の連続した要素を取り出します。この関数は、どちらかのインデックスが与えられたリストの有効なインデックスの範囲外である場合にエラーを返します。

slice(list, startindex, endindex)

tfvarsファイル

terraform.tfvars は、変数を定義しているファイルです。

# terraform.tfvars
AWS_REGION="ap-northeast-1"

Resource

リソースはTerraformで最も重要な要素です。各リソースブロックは、仮想ネットワークやコンピュートインスタンス、DNSレコードのような上位コンポーネントなど、1つ以上のインフラオブジェクトを記述します。

# resource.tf
provider "aws" {
  
}

variable "AWS_REGION" {
  type = string
}

variable "AMIS" {
  type = map(string)
  default = {
    ap-northeast-1 = "my ami"
  }
}

resource "aws_instance" "example1" {
  ami = var.AMIS[var.AWS_REGION]
  instance_type = "t2.micro"
}
resource "aws_instance" "example2" {
  ami = var.AMIS[var.AWS_REGION]
  instance_type = "t2.small "
}

上記の例ではAWSのインスタンスを起動するための内容が定義されています。

コマンド:init

terraform init コマンドはTerraformの設定ファイルを含む作業ディレクトリを初期化します。新しいTerraformの設定を書いたり、バージョン管理から既存の設定をクローンした後に最初に実行するコマンドです。このコマンドは複数回実行しても問題ありません。

$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v5.23.1...
- Installed hashicorp/aws v5.23.1 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

上記コマンドでプラグインがインストールされ、terraform.lock.hcl ファイルが作成されます。

オプション

以下のオプションは、すべての(またはいくつかの)初期化ステップに適用されます

  • -input=true 必要なら入力を求める。falseの場合、入力が必要であればエラーになる。
  • -lock=false ステート関連操作中のステート・ファイルのロックを無効にする。
  • -lock-timeout=<継続時間> Terraformが状態ロックを取得するまでの待機時間をオーバーライドする。デフォルトは0s(0秒)で、ロックが他のプロセスによって既に保持されている場合は即座に失敗する。
  • -no-color コマンド出力のカラーコードを無効にする。
  • -upgrade モジュールとプラグインを、それぞれのインストール手順の一部としてアップグレードします。

ソースモジュールのコピー

デフォルトでは、terraform init は作業ディレクトリにすでに設定が含まれていると仮定し、その設定を初期化しようとします。

オプションとして、-from-module=MODULE-SOURCE オプションを指定することで、空のディレクトリに対して init を実行することができます。この場合、他の初期化ステップが実行される前に、指定されたモジュールがターゲットディレクトリにコピーされます。

この特別な操作モードは、2つのユースケースをサポートしています。

  • バージョン管理のソースがあれば、バージョン管理から設定を参照し、その作業ディレクトリを初期化する省略記法の役割を果たすことができます。
  • ソースが設定を参照している場合、それをローカルディレクトリにコピーして、新しい設定の基礎として使用することができます。

日常的に使用する場合は、バージョン管理システム独自のコマンドを使用して、バージョン管理から個別に設定を参照することが推奨されます。こうすることで、必要なときにバージョン管理システムに追加のフラグを渡したり、terraform init を実行する前に他の準備ステップ(設定の生成や認証情報の有効化など)を実行したりすることができます。

バックエンドの初期化

init の間、バックエンドの設定のためにルート設定ディレクトリが参照され、選択されたバックエンドが与えられた設定を使って初期化されます。

既に初期化されたバックエンドで init を再実行すると、新しいバックエンド設定を使用するように作業ディレクトリが更新されます。バックエンドの設定を更新するには、-reconfigure-migrate-state のどちらかを指定しなければなりません。

migrate-state オプションは、既存の状態を新しいバックエンドにコピーしようとします。変更内容によっては、ワークスペース状態の移行を確認するための対話型プロンプトが表示されます。force-copy オプションは、これらのプロンプトを抑制し、移行の質問に “yes” と答えます。force-copy を有効にすると、自動的に -migrate-state オプションも有効になります。

reconfigure オプションは、既存の構成を無視し、既存の状態の移行を防止します。

バックエンドの設定をスキップするには、-backend=false を使用します。他の init ステップの中には初期化されたバックエンドを必要とするものがありますので、作業ディレクトリが既に特定のバックエンド用に初期化されている場合にのみこのフラグを使用することが推奨されます。

backend-config=… オプションは、バックエンドの設定が動的であったり繊細であったりするために設定ファイルで静的に指定できない場合に、バックエンドの部分的な設定に使用することができます。

子モジュールの取り付け

init の間、設定はモジュールブロックを検索し、参照されたモジュールのソースコードは、そのソース引数で与えられた場所から取得されます。

モジュールが既にインストールされている状態で init を再実行すると、前回の init 以降に設定に追加されたモジュールのソースはインストールされますが、既にインストールされているモジュールは変更されません。upgrade を使用すると、この動作をオーバーライドし、すべてのモジュールを利用可能な最新のソースコードに更新します。

子モジュールのインストールをスキップするには、-get=false を使用してください。他の init ステップの中には、モジュールツリーが完了したときにのみ完了するものがありますので、作業ディレクトリが以前に子モジュールで初期化されている場合にのみ、このフラグを使用することをお勧めします。

プラグインのインストール

ほとんどのTerraformプロバイダはプラグインとしてTerraformとは別に公開されています。init 時に、Terraformはプロバイダへの直接参照と間接参照の両方を設定から検索し、それらのプロバイダのプラグインをインストールしようとします。

公開されているTerraformレジストリかサードパーティのプロバイダレジストリのどちらかで公開されているプロバイダについては、terraform init は自動的に必要なプロバイダプラグインを見つけ、ダウンロードし、インストールします。オリジンレジストリからプロバイダをインストールできない、またはインストールしたくない場合は、CLI設定のプロバイダインストール設定を使用して、Terraformがプロバイダをインストールする方法をカスタマイズできます。

インストールに成功すると、Terraformは選択したプロバイダに関する情報を依存関係ロックファイルに書き込みます。このファイルをバージョン管理システムにコミットして、将来 terraform init を再度実行したときにTerraformがまったく同じバージョンのプロバイダを選択するようにしてください。Terraformに依存関係ロックファイルを無視して新しいバージョンのインストールを検討させたい場合は、-upgrade オプションを使います。

terraform init のプラグインの動作は以下のオプションで変更できます

  • -upgrade – 以前に選択したすべてのプラグインを、設定のバージョン制約に適合する最新バージョンにアップグレードします。これにより、Terraformは依存関係ロックファイルに記録された選択を無視し、設定されたバージョン制約に合致する利用可能な最新バージョンを選択するようになります。
  • -plugin-dir=PATH – CLIの設定で filesystem_mirror として設定されているかのように、指定されたディレクトリからのみプラグインを読み込むようにプラグインのインストールを強制します。特定のファイルシステムミラーを日常的に使用するのであれば、Terraformのインストール方法をグローバルに設定することをお勧めします。plugin-dir は、現在開発中のプロバイダプラグインのローカルビルドをテストする場合など、例外的な場合に一度だけオーバーライドするために使うことができます。
  • -lockfile=MODE – 依存ロックファイル・モードを設定します。

ロックファイル・モードの有効な値は以下の通りです。

  • readonly : ロックファイルの変更を抑制するが、すでに記録されている情報と照合してチェックサムを検証する。upgrade フラグと競合する。サードパーティーの依存関係管理ツールを使ってロックファイルを更新する場合、いつ変更されるかを明示的に制御できると便利です。

terraform initの自動実行

Terraformを変更管理とデプロイメントパイプラインの重要な一部として使用しているチームにとって、Terraformの実行をある種の自動化でオーケストレーションすることは、実行間の一貫性を保証し、バージョン管理フックとの統合のような他の興味深い機能を提供するために望ましいかもしれません。

このような環境で init を実行する場合、再インストールを繰り返さないようにプラグインをローカルで利用可能にするオプションなど、いくつかの特別な懸念事項があります。詳しくはRunning Terraform in Automationチュートリアルを参照してください。

コマンド:apply

terraform apply コマンドは、Terraformプランで提案されたアクションを実行します。実際にAWSのEC2を起動するなどが可能です。

# instance.tf
provider "aws" {
  access_key = "ACCESS_KEY_HERE"
  secret_key = "SECRET_KEY_HERE"
  region     = "us-east-1"
}

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

$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                                  = "ami-0d729a60"

(...省略)

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を入力)

aws_instance.example: Creating...
aws_instance.example: Still creating... [10s elapsed]
aws_instance.example: Creation complete after 20s [id=i-0d729a60]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

自動プラン・モード

保存された計画ファイルを渡さずに terraform apply を実行すると、Terraformは自動的に terraform plan を実行したかのように新しい実行計画を作成し、その計画を承認するよう促し、指示されたアクションを実行します。すべてのプランニングモードとプランニングオプションを使って、Terraformがどのようにプランを作成するかをカスタマイズすることができます。

auto-approve オプションを渡すと、Terraformに確認を求めずにプランを適用するように指示できます。

保存プランモード

保存したプランファイルを terraform apply に渡すと、Terraformは確認のプロンプトを出さずに保存したプランのアクションを実行します。Terraformをオートメーションで実行する際には、この2ステップのワークフローを使うとよいでしょう。

terraform show を使って、保存したプランファイルを適用する前に検査します。

保存されたプランを使用する場合、追加のプランニングモードやオプションを指定することはできません。これらのオプションはTerraformがどのアクションを実行するかという決定にのみ影響し、プランファイルにはそれらの決定の最終結果が含まれます。

Planのオプション

保存されたプランファイルがない場合、terraform applyterraform plan で使用可能なすべてのプランニングモードとプランニングオプションをサポートします。

プランモード:リモートオブジェクトをすべて破棄する計画を作成する -destroy と、Terraform の状態とルートモジュールの出力値を更新する計画を作成する -refresh-only があります。
プランオプション:Terraformがどのリソースインスタンスを置き換えるかを指定したり、Terraformの入力変数を設定したりします。

Applyのオプション

以下のオプションは、apply コマンドの実行方法と apply 操作の報告方法を変更します。

  • -auto-approve – 適用前にプランのインタラクティブな承認をスキップします。Terraformはプランファイルを渡されたことを承認とみなすので、この場合プロンプトは表示されません。
  • -compact-warnings – 警告が少なくとも1つのエラーを伴っており、そのため警告文がエラーのコンテキストとして有用である場合を除き、要約メッセージのみを含むコンパクトな形式で警告メッセージを表示する。
  • -input=false – Terraformの対話的なプロンプトをすべて無効にします。これはTerraformが対話的にプランの承認を求めるプロンプトも表示しないようにするため、Terraformは保守的にプランの適用を希望していないとみなし、操作が失敗する原因になることに注意してください。
  • -json – マシンが読み取り可能なJSON UI出力を有効にします。これは -input=false を意味しますので、設定を続行するには、未割り当ての変数値がない必要があります。このフラグを有効にするには、-auto-approve フラグも有効にするか、以前に保存した計画を指定する必要があります。
  • -lock=false – 操作中に状態ロックを保持しない。これは、同じワークスペースに対して他の人が同時にコマンドを実行する可能性がある場合に危険です。
  • -lock-timeout=DURATION-lock=false でロックを無効にしない限り、Terraformがエラーを返すまでの期間、ロックの取得を再試行するよう指示する。duration構文は、数値の後に時間単位の文字を続けます。
  • -no-color – 出力中の端末フォーマットシーケンスを無効にします。ターミナルフォーマットを解釈できないシステムでTerraformの出力がレンダリングされるような状況でTerraformを実行する場合に使用します。
  • -parallelism=n – Terraformがグラフをウォーキングする際の同時操作数を制限します。デフォルトは10です。parallelismの設定は高度な操作であり、Terraformを普通に使う上では必要ありません。特定の特殊な使用ケースや、Terraformの問題のデバッグに役立つかもしれません。
  • terraform plan のすべてのプランニングモードとプランニングオプション – Terraformがどのようにプランを作成するかをカスタマイズする。プランファイルを保存せずに terraform apply を実行した場合のみ利用可能。

ローカルバックエンドのみを使用する設定の場合、terraform apply-state-state-out-backup のレガシーオプションも受け付けます。

コマンド:destroy

作成したインスタンスを削除する場合は、terraform destroy コマンドを使います。

$ terraform destroy

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # aws_instance.example will be destroyed
  - resource "aws_instance" "example" {
  
(...省略)

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: 
  
(yesと入力)

aws_instance.example: Destroying... [id=i-0d729a60]
aws_instance.example: Still destroying... [id=i-0d729a60, 10s elapsed]
aws_instance.example: Destruction complete after 20s

Destroy complete! Resources: 1 destroyed.

terraform destroy コマンドは、特定のTerraformコンフィギュレーションで管理されているすべてのリモートオブジェクトを破棄する便利な方法です。

本番環境では通常、長期間のオブジェクトを破棄することはありませんが、Terraformは開発目的で一時的なインフラを管理するために使われることがあります。

使用方法

このコマンドは、以下のコマンドの便宜的なエイリアスに過ぎません。

terraform apply -destroy

そのため、このコマンドは terraform apply が受け付けるオプションのほとんどを受け付けますが、プランファイルの引数は受け付けず、プランニングモードは “destroy “を強制的に選択します。

また、次のコマンドを実行することで、destroy の効果を見るために、破壊計画を作成することもできます。

terraform plan -destroy

これは terraform plan を破壊モードで実行し、実行せずに破壊の変更案を表示します。

コマンド:plan

terraform plan コマンドは実行計画を作成し、Terraformがインフラストラクチャに行う予定の変更をプレビューすることができます。

$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                                  = "ami-0d729a60"
      
(...省略)

      + vpc_security_group_ids               = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

デフォルトでは、Terraformがプランを作成するとき、以下のようになります。

  • すでに存在するリモートオブジェクトの現在の状態を読み込み、Terraformの状態が最新であることを確認する。
  • 現在の設定と以前の状態を比較し、違いがあれば指摘します。
  • リモートオブジェクトを設定と一致させるための変更アクションを提案します。

plan コマンドだけでは、提案された変更が実際に実行されるわけではありません。このコマンドは、変更を適用する前に、提案された変更が期待したものと一致しているかどうかをチェックするために使用したり、変更をチームで共有し、より広範なレビューを受けるために使用したりすることができます。

Terraformがリソースインスタンスやルートモジュールの出力値に変更が必要ないことを検出した場合、terraform plan は何もする必要がないことを報告します。

対話型ターミナルで直接Terraformを使用していて、Terraformが提案する変更を適用することが予想される場合、代わりに terraform apply を直接実行することができます。デフォルトでは、apply コマンドは自動的に新しいプランを生成し、承認を求めるプロンプトを表示します。

オプションの -out=FILE オプションを使うと、生成されたプランをディスク上のファイルに保存することができ、後でそのファイルを terraform apply に追加引数として渡して実行することができます。この2ステップのワークフローは、主にTerraformをオートメーションで実行する場合を想定しています。

out=FILE オプションをつけずにterraform planを実行すると、推測計画が作成されます。

実際のインフラストラクチャに変更を加えるためにバージョン管理とコードレビューのワークフローを使用しているチームでは、開発者は、コードレビューに提出する前に、変更の効果を検証するために推測計画を使用することができます。しかし、その間にターゲットシステムに加えられた他の変更によって、設定変更の最終的な効果が以前の推測計画で示されたものと異なる可能性があることを考慮することが重要です。したがって、適用する前に、常に最終的な非推測計画を再チェックして、それがまだあなたの意図と一致していることを確認する必要があります。

使い方

plan サブコマンドは、現在の作業ディレクトリでルート・モジュールの設定を探します。

plan コマンドはTerraformのメインコマンドの1つなので、以下のセクションで説明する様々なオプションがあります。しかし、ほとんどの場合、これらのオプションを設定する必要はないはずです。通常、Terraformの設定は、定型的な作業であれば特別なオプションを追加しなくても動作するように設計されているはずだからです。

このページの残りのセクションでは、様々なオプションについて説明します。

  • プランニングモード:リモートシステムを自分の設定に合わせて変更することだけが目的ではない、特殊な状況下で使用できる特別な代替プランニングモードがいくつかあります。
  • プランニングオプション:特別なプランニングモードと並行して、特別なニーズに合わせてプランニングプロセスをカスタマイズするために設定できるオプションもいくつかあります。
    • リソースターゲット(Resource Targeting)は、特別な計画オプションの1つですが、これにはいくつかの重要な注意事項があります。
  • その他のオプション:これらは、生成される計画の内容をカスタマイズするのではなく、計画コマンド自体の動作を変更します。

プランニングモード

前節ではTerraformのデフォルトのプランニング動作について説明しましたが、これは設定の変更に合わせてリモートシステムを変更するものです。Terraformには2つのプランニングモードがあり、それぞれ異なる意図した結果を持つ計画を作成します。これらのオプションは terraform planterraform apply の両方で利用できます。

  • Destroy mode: 現在存在するすべてのリモートオブジェクトを破棄し、空のTerraform状態を残すことを目的としたプランを作成します。terraform destroyの実行と同じです。Destroyモードは、一時的な開発環境のように、開発タスクが完了すると管理オブジェクトが使えなくなるような場合に便利です。destroy コマンドラインオプションでdestroyモードを有効にします。
  • Refresh-onlyモード: Terraformの状態やルートモジュールの出力値を、Terraform外のリモートオブジェクトに加えられた変更に合わせて更新することのみを目的としたプランを作成します。これは、通常のワークフロー以外で1つ以上のリモートオブジェクトを意図的に変更し(例えばインシデント対応中)、その変更とTerraformの記録を照合する必要がある場合に便利です。refresh-only コマンドラインオプションを使ってリフレッシュオンリーモードを有効にします。

どの代替モードも選択されていないときにTerraformが使用するデフォルトのプランニングモードについて説明する必要がある状況では、”Normal mode “と呼びます。これらの代替モードは特殊な状況でのみ使用されます。

計画モードはすべて相互に排他的なので、デフォルト以外の計画モードをアクティブにすると “Normal “計画モードは無効になり、同時に複数の代替モードを使うことはできません。

プランニング・オプション

代替計画モードに加えて、計画動作を変更できるオプションがいくつかあります。これらのオプションはテラフォーム計画とテラフォーム応用の両方で利用できます。

  • -refresh=false – 設定の変更をチェックする前にTerraformの状態をリモートオブジェクトと同期するデフォルトの動作を無効にします。これにより、リモートAPIリクエストの回数を減らすことで計画操作を高速化できます。ただし、refresh=false を設定すると、Terraformが外部からの変更を無視するようになり、計画が不完全または不正確になる可能性があります。refresh=falserefresh-only プランニングモードで使用することはできません。これはプランニング操作全体を事実上無効にしてしまうからです。
  • -replace=ADDRESS – リソースインスタンスを指定されたアドレスに置き換えるようTerraformに指示します。これは1つ以上のリモートオブジェクトがデグレしてしまった場合に有用で、同じ構成の置換オブジェクトを使用して不変のインフラパターンに合わせることができます。Terraformは、指定されたリソースが通常 “update “アクションを引き起こすか、まったくアクションを引き起こさない場合、”replace “アクションを使用します。複数のオブジェクトを一度に置き換えるには、このオプションを複数回指定します。-replace-destroy オプションとは併用できず、Terraform v0.15.2以降でのみ利用可能です。それ以前のバージョンでは terraform taint を使って同様の結果を得ることができます。
  • -target=ADDRESS – Terraformに、指定されたアドレスにマッチするリソースインスタンスと、それらのインスタンスが依存するオブジェクトのみに計画を集中させるように指示します。
  • -var 'NAME=VALUE' – コンフィギュレーションのルートモジュールで宣言された1つの入力変数に値を設定します。複数の変数を設定するには、このオプションを複数回使用します。
  • -var-file=FILENAME – 「tfvars」ファイルからの定義を使って、コンフィギュレーション のルート・モジュールで宣言された多数の入力変数の値を設定します。このオプションを複数回使用すると、複数のファイルから値を取り込むことができます。

-var オプションと -var-file オプション以外にも、ルート・モジュールの入力変数に値を設定する方法がいくつかあります。詳しくは「ルート・モジュールの変数に値を割り当てる」を参照してください。

コマンドラインでの入力変数

-var コマンドラインオプションを使えば、ルート・モジュールで宣言された入力変数の値を指定できる。

しかし、そのためにはコマンドラインシェルとTerraformの両方で解析可能なコマンドラインを記述する必要があり、引用符やエスケープシーケンスを多用する式の場合は複雑になる可能性があります。ほとんどの場合、-var-file オプションを使うことをお勧めします。実際の値を別のファイルに書き、Terraformがシェルの解析結果を解釈するのではなく、直接解析できるようにします。

LinuxやmacOSのようなシステム上のUnixスタイルのシェルで -var を使うには、シェルが値を文字通りに解釈するように、オプションの引数をシングルクォート’で書くことを推奨する

terraform plan -var 'name=value'

意図した値にシングルクォートも含まれている場合は、シェルが正しく解釈できるようにエスケープする必要があります。また、バックスラッシュ・エスケープ文字が意味を持つように、クォートされたシーケンスを一時的に終了させる必要があります。

terraform plan -var 'name=va'\''lue'

WindowsでTerraformを使う場合は、Windowsコマンドプロンプト(cmd.exe)を使うことをお勧めします。WindowsコマンドプロンプトからTerraformに変数値を渡すときは、引数を二重引用符「”」で囲んでください。

terraform plan -var "name=value"

意図した値にリテラルな二重引用符が含まれる場合は、バックスラッシュでエスケープする必要があります。

terraform plan -var "name=va\"lue"

Windows上のPowerShellはリテラル引用符を外部プログラムに正しく渡せないので、Windows上でPowerShellを使ってTerraformを使うことはお勧めしません。代わりにWindowsコマンドプロンプトを使ってください。

変数値を記述するための適切な構文は、変数の型制約によって異なります。プリミティブ型のstring、number、およびboolはすべて、上記の例に示されているように、シェルで要求される以外の特別な句読点を持たない直接的な文字列値を期待します。list、map、set型や特殊なanyキーワードを含む他のすべての型制約については、値を表す有効なTerraform言語式を記述し、必要な引用符やエスケープ文字を記述して、シェルからTerraformに文字通りに通過するようにする必要があります。例えば、list(string)型の制約の場合です。

# Unix-style shell
terraform plan -var 'name=["a", "b", "c"]'

# Windows Command Prompt (do not use PowerShell on Windows)
terraform plan -var "name=[\"a\", \"b\", \"c\"]"

環境変数を使用して入力変数を設定する場合も、同様の制約が適用されます。ルート・モジュール入力変数を設定するさまざまな方法の詳細については、「ルート・モジュール変数に値を割り当てる」を参照してください。

リソース・ターゲティング

-target オプションを使うと、Terraformの注意をリソースのサブセットだけに向けることができます。制約を指定するにはリソースアドレス構文を使います。Terraformはリソースアドレスを以下のように解釈します。

  • 指定されたアドレスが特定のリソースインスタンスを特定している場合、Terraformはそのインスタンスだけを選択します。count または for_each が設定されているリソースの場合、リソースインスタンスアドレスには aws_instance.example[0] のようにインスタンスインデックス部分を含める必要があります。
  • 指定されたアドレスがリソース全体を識別する場合、Terraformはそのリソースのすべてのインスタンスを選択します。count または for_each が設定されているリソースの場合、これはそのリソースに現在関連付けられているすべてのインスタンスインデックスを選択することを意味します。シングルインスタンスリソース(countfor_each も設定されていない)の場合、リソースアドレスとリソースインスタンスアドレスは同一であるため、この可能性は適用されません。
  • 指定されたアドレスがモジュールインスタンス全体を識別している場合、Terraformはそのモジュールインスタンスとその子モジュールインスタンスに属するすべてのリソースのすべてのインスタンスを選択します。

Terraformは、あなたが直接ターゲットとした1つまたは複数のリソースインスタンスを選択すると、その選択範囲が直接または間接的に依存している他のすべてのオブジェクトにも拡張されます。

このターゲティング機能は、ミスからの回復やTerraformの制限を回避するような例外的な状況のために提供されています。日常的な操作に -target を使うことは推奨されません。なぜなら、これは設定のドリフトを検出できなかったり、リソースの真の状態が設定とどのように関連しているのか混乱したりする可能性があるからです。

非常に大きな設定の孤立した部分に対して操作する手段として `-target` を使うのではなく、大きな設定をいくつかの小さな設定に分割して、それぞれが独立して適用できるようにするのが望ましいです。データ・ソースを使用して、他の設定で作成されたリソースに関する情報にアクセスできるため、複雑なシステム・アーキテクチャを、独立して更新できる、より管理しやすい部分に分割できます。

Terraformの型

Terraform言語では、値に以下の型を使用します。

  • string"hello" のようなテキストを表す Unicode 文字列。
  • number : 数値。number 型は、15のような整数も、6.283185のような小数も表すことができます。
  • bool : 真偽どちらかのブール値。bool 値は条件ロジックで使用できます。
  • list(または tuple) : ["us-west-1a", "us-west-1c"] のような一連の値。リスト内の要素を、ゼロから始まる連続した整数で識別します。
  • set : 二次識別子や順序を持たない一意な値の集まり。
  • map(または object ):{name = "Mabel", age = 52} のように、名前付きラベルで識別される値のグループ。
  • null : 不在または省略を表す値。リソースの引数をnull に設定した場合、Terraformは完全に省略したかのように振る舞います。引数にデフォルト値がある場合はそれを使用し、引数が必須の場合はエラーを発生させます。nullは条件式で最も有用で、条件を満たさない場合に動的に引数を省略することができます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です