1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Terraform基礎知識

Last updated at Posted at 2022-12-06

Terrafromの自分用メモ


参考

主なワークフロー

  1. Initialize
    • Terraforを実行するための、作業ディレクトリを準備する
    • initコマンドでTerraformやプロバイダのバージョンをアップグレードもできる
  2. Plan
    • 変更を適用する前にプレビューする
      • 実環境に反映されることはない
    • Terraformの設定と現状のリソースを照合する
      • 特定のリソースをターゲットにすることも可能
      • 状態ファイルと実際の構成を照合することも可能
  3. Apply
    • Terraform の設定によって定義された変更を実行し、リソースを作成、更新、破棄する
    • 部分的に完了した適用はロールバックされない
      • 適用中にエラーになった場合、機能しない構成になっている可能性がある

主なファイル

Initialize

versions.tf

  • Terrafrom本体等のバージョンを制限する
    • 複数人開発時のバージョン差異によるリスクを低減できる
  • バージョンは「MAJOR.MINOR.PATCH」と表現される
    • 例えばマイナーバージョンが上がった場合、
      パッチはそのマイナーバージョンアップに含まれることになる
  • バージョン表記は以下
    • 0.15.0:v0.15.0のみ許容する
    • >= 0.15:v0.15以上(v1.0.0含めて)を許容する
    • ~> 0.15.0:0.15.Xは許容する
      • マイナーおよびメジャーバージョンアップはしないがパッチは適用したい場合
    • >= 0.15, < 2.0.0:v0.15.0以上、v2.0.0未満を許容する

terraform {
  required_version = ">= 1.0.8"  # Terrafromのバージョン
  required_providers {
    aws = {
      source = "hashicorp/aws"   # 利用するプロバイダを指定
      version = "3.63.0"         # プロバイダのバージョン
    }
  }
}

.terraform.lock.hcl

  • プロバイダバージョンを指定するファイル
  • 本ファイルが存在しない場合、versions.tfからプロバイダのバージョンを決定する
  • versions.tfに記述がなく、本ファイルも存在しない場合は
    最新のバージョンがダウンロードされる

# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.

provider "registry.terraform.io/hashicorp/aws" {
  version     = "3.63.0"
  constraints = "3.63.0"
  hashes = [
    "h1:FyU8TUgpwfu+O+k+Uu58I/JWlEZk2PzQLJMluuaIQ=",
    ## ...
    "zh:fd634e973eb2b6483a1ce92518093d04cb496f8e83ffcf3f0c4cad8c18f4c",
  ]
}

.terraform

  • プロジェクトのプロバイダーとモジュールを格納するディレクトリ
  • plan, applyを実行するときに、これらのコンポーネントは参照される
  • 直接変更しないこと

$ tree .terraform/providers
.terraform/providers
└── registry.terraform.io
    └── hashicorp
        └── aws
            └── 3.63.0
                └── linux_amd64
                    └── terraform-provider-aws_v3.63.0_x5

5 directories, 1 file

variables.tf

  • 変数の設定ファイル
  • 変数の宣言はどこでも問題ないが、通例としてvariables.tfに記述する

使い方例

  • 起動するインスタンス数を環境ごとに変える
  • IPアドレスレンジが環境ごとに被らないようにする
  • タグ付けを環境ごとに分ける
  • apply時に変数に任意の値を入力する
    • terraform.tfvarsに入力が必要な値をまとめて定義、読み込ませることも可能

Apply

outputs.tf

  • 出力の設定ファイル
  • 出力の宣言はどこでも問題ないが、通例としてoutputs.tfに記述する
  • 別のTerraformワークスペースのデータソースとして利用する
output "aws_instance_tfer--i-bb85f7df195ffc5_aws-cloud9-bb85f356b29a1f096d8267_id" {
  value = aws_instance.tfer--i-bb85f7df195ffc5_aws-cloud9-bb85f356b29a1f096d8267.id
}

output "aws_instance_tfer--i-d58229a1f09b18_bluegreen_id" {
  value = aws_instance.tfer--i-d5829a1f0923b18_bluegreen.id
}

terraform.tfstate

  • インフラに関する情報を状態を格納するファイル
    • apply時に生成されるファイル
    • 状態ファイルに書き込み後、実体のリソースが更新される
  • 設定によって作成されたリソースを追跡し、実体のリソースにマッピングする
  • 直接変更しないこと
  • plan時はtfファイルとterraform.tfstateが比較され、差分が表示される
    • 実環境と比較していないので、実環境とterraform.tfstateに差分があるのはNG

変数

  1. 入力変数
    • 関数の引数のようなもの
    • 手を加えずにモジュールを別環境で共有できるようになる
  2. 出力変数
    • 関数の戻り値のようなもの
    • インフラに関する情報をコマンドラインから利用できる
    • 他のTerraform構成が利用できるようにできる
  3. ローカル変数
    • 関数の一時的なローカル変数のようなもの
    • 関連するローカル値のセットは、1つのローカルブロックにまとめて宣言できる
    • 一箇所で簡単に値を変更できることが主な利点
      • 多くの場所で使用されるが、その値が将来変更される可能性がある場合に使用する
      • 実際に使われている値を隠してしまうので使いすぎは注意

入力変数

定義例

variable "image_id" {
  type = string
}

variable "availability_zone_names" {
  type    = list(string)
  default = ["us-west-1a"]
}

variable "docker_ports" {
  type = list(object({
    internal = number
    external = number
    protocol = string
  }))
  default = [
    {
      internal = 8300
      external = 8300
      protocol = "tcp"
    }
  ]
}

各項目

variable

  • 同じモジュール内のすべての変数の中で一意の値

default

  • デフォルト値が存在する場合、変数はオプションとみなされる
  • 値が設定されていない場合、デフォルト値が使用される
  • リテラル値であること
    • 設定内の他のオブジェクトを参照することはできない

type

  • 変数の値の型宣言
  • ない場合は、どのような型の値でも許容する
  • 宣言することで間違った型が使われた場合、エラーメッセージが返る

description

  • 各変数の目的を簡単に説明できる
  • 説明文は、その変数の目的と、どのような値が期待されるかを簡潔に説明する
  • モジュールを使う人の視点で書かれるべきもの
    • モジュールをメンテする人に対する解説はコメントアウトを使う
validation
  • 特定の変数に対するカスタム検証ルールを指定することができる
sensitive
  • 計画や適用の出力にその値を表示するのを防ぐ
  • エラー出力等では表示される場合もあるので注意
nullable
  • 変数に null 値を代入してよいかどうかを制御
  • デフォルト値はtrue
  • trueの場合、変数値がnullであることを常に考慮する必要がある
  • trueの場合、入力引数としてNULLを渡すと、デフォルト値が上書きされる
  • falseかつデフォルト値がある場合、入力引数がNULLのとき、デフォルト値が使用される

利用方法

  • var.で利用する
  • 環境変数を設定し、利用する
  • 変数のロード順序は以下、後勝ち
    1. 環境変数
    2. terraform.tfvars
    3. terraform.tfvars.json
    4. *.auto.tfvars または *.auto.tfvars.json
    5. コマンドラインのオプション
      • 記載順に処理される

環境変数

  • TF_VAR_の後に宣言された変数名をつけた環境変数が読み込まれる
  • Terraformを自動化やTerraformコマンド実行時に便利
  • 大文字小文字は区別される

設定例

$ export TF_VAR_image_id=ami-abc123
$ terraform plan
...

変数定義ファイル

  • terraform.tfvarsまたはterraform.tfvars.jsonという名前で作成される
  • キーバリューのみ記述する
  • 定義された変数の値が変数定義ファイルにない場合、エラーにはならない
  • 定義されていない変数の値が変数定義ファイルにある場合、エラーになる

設定例

terraform.tfvars
image_id = "ami-abc123"
availability_zone_names = [
  "us-east-1a",
  "us-west-1c",
]
terraform.tfvars.json
{
  "image_id": "ami-abc123",
  "availability_zone_names": ["us-west-1a", "us-west-1c"]
}

コマンドライン

  • plan、apply時に-varオプションとして利用する
    • 環境ごとに値を使い分けるとき便利
  • 変数定義ファイルを作成し、plan、apply時に-var-fileオプションとして利用する

設定例

terraform apply -var="image_id=ami-abc123"
terraform apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro"
terraform apply -var='image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}'
terraform apply -var-file="testing.tfvars"

使い方例

resource "aws_instance" "example" {
  instance_type = "t2.micro"
  ami           = var.image_id
}

出力変数

output "instance_ip_addr" {
  value = aws_instance.server.private_ip
}

ローカル変数

記載例

locals {
  # Ids for multiple sets of EC2 instances, merged together
  instance_ids = concat(aws_instance.blue.*.id, aws_instance.green.*.id)
}

locals {
  # Common tags to be assigned to all resources
  common_tags = {
    Service = local.service_name
    Owner   = local.owner
  }
}

利用例

resource "aws_instance" "example" {
  # ...

  tags = local.common_tags
}

backend

  • Terraformが状態データファイルを保存する場所のこと

terraform {
  backend "s3" {
    bucket = "mybucket"
    key    = "path/to/my/key"
    region = "us-east-1"
  }
}

module

  • Terraformでは少なくともルートモジュールが1つある
  • モジュールは他のモジュールを呼び出すことができる

モジュールの呼び出しかた

module "servers" {
  source = "子モジュールへの相対パス"
  xxx = "子モジュールで定義されている変数の値"
}

data source

  • Terraformの外部で定義された情報を利用する
  • AWSのdata sourceを調べられる

# Find the latest available AMI that is tagged with Component = web
data "aws_ami" "web" {
  filter {
    name   = "state"
    values = ["available"]
  }

  filter {
    name   = "tag:Component"
    values = ["web"]
  }

  most_recent = true
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.web.id
  instance_type = "t1.micro"
}

感想

  • アプリエンジニアは変数の持ち方など、知見を活かせられそう
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?