Terraform

個人的な印象:


terraformでDB user作成

注意点:

記事:


Infracos Cloud: terraformコードからコスト見積もり/差分を出してくれるSaaS


ガイドライン


terraform本体のコードリーディング

記事:


mysql user/password等を作成する


OpenTofu: OSS版terraform


optional(type): 省略可能な変数定義

記事:


さくらのクラウド(さくらインターネット)

記事:


変数の外部定義と優先度

上から順に読み込まれ、同名は上書きされる

Input Variables - Configuration Language | Terraform | HashiCorp Developer


Pluralith: terraformコードから構成図を作図するサービス

記事:


blockを動的に定義し、パラメータ化する

variable "heroku_app_organization" {
  description = ""
  type = object({
    name = string
  })
  default = {
    name = null
  }
}

resource "heroku_app" "main" {
...

  dynamic "organization" {
    for_each = var.heroku_app_organization.name == null ? [] : [var.heroku_app_organization]
    content {
      name = organization.value.name
    }
  }
}

機密情報を暗号化して保存する

sensitiveの変更を出力したい時:

記事:


排他仕様の変数に代入


data.http: httpリクエストを送る


tfcmt: plan結果を整形してCI/DIの改善

記事:


templatefile(): ファイル中の変数を展開


moved: リソース名変更等のリファクタリング

記事:

rangeでloopさせる


for: ループ


v1.0以降の対応


URLからOIDC fingerprintを取得

記事:


機密情報を出力したい時

output example_password {
  value = nonsensitive(aws_db_instance.example.password)
}

記事


セキュリティチェック


untaint: 失敗したstate fileを解決済みとしてマークする

例:

解決:

terraform untaint aws_db_instance.main

算術演算子


plan時に色を付けない


GitHub actionsでの連携


console: 対話型で式を検証


dynamic block: リソース内の同名blockのループ

variable "sg_ssh_ingress" {
  default = [
    {
      cidr_blocks = ["xxx.xxx.xxx.xxx/32"]
      description = "ssh from AAA"
      security_groups = []
      self        = false
    },
    {
      cidr_blocks = ["xxx.xxx.xxx.xxx/32"]
      description = "ssh from BBB"
      security_groups = []
      self        = false
    },
...
  ]
}

resource "aws_security_group" "bastion" {
...
  dynamic "ingress" {
    for_each = var.sg_ssh_ingress
    content {
      from_port       = 22
      to_port         = 22
      protocol        = "tcp"
      cidr_blocks     = ingress.value.cidr_blocks
      security_groups = ingress.value.security_groups
      description     = ingress.value.description
      self            = ingress.value.self
    }
  }
...
}

for_each: ループ

v0.12.6以降のループ処理について。

countの問題点:

Manage Similar Resources with For Each | Terraform - HashiCorp Learn:


key, value以上の複数のパラメータを指定したい場合


for_eachリソースをoutputしたい場合

output "user_home" {
  value = [ for value in null_resource.user : value.home ]
}

list(map) 型をfor_eachでループ


Registry: 公開moduleの使用


肥大化した.terraformディレクトリの削除


CodePipelineから実行


public ipの取得


リファクタリング


planやapplyの高速化

リソースが増えてくると、planやapplyがどんどん遅くなる。


listやmapの入れ子

v0.11とv0.12では挙動がまったく異なる場合がある。また、関数も入れ子だと動かない場合がある。


Terraform Cloud:


graph: リソースの依存関係を画像で出力

Cycleエラーの解消などに利用できる。


count: ループ処理

EC2をN台作る等、同じ種類のリソースを複数定義する時に使える。


csv, json, yaml を読む


data.external: 外部コマンドの結果を取り込む


data.remote_state: 他のtfstateのリソースを参照する


Atlantis: terraformをpull requestベースで駆動する


providerのバージョン固定


providerの更新

terraform init -upgrade

# or
rm -rf .terraform
terraform init

terraformバージョンの固定

terraformはバージョンが0.0.1でも違うとコードの互換性が無くなる事が多い。
そのためバージョンを固定したい場合がある。


tfenv: 複数バージョンの切替

terraformはサイズが大きく、バージョンアップも頻繁なので古いバージョンを消したい。


v0.14


upgrade


v0.13


エラーの修正


upgrade


v0.12

v0.11.x以下とコードの互換性が無くなかった。


ベストプラクティス


module: リソースのモジュール化

同一のリソースを名前やアカウント、リージョンだけ作成したい時に、コードを共通化できる。

不便な点:

moduleを使わない方法:

記事:


module内で別providerの参照


module内で作成されたリソースの参照


便利な関数


VSCode(Visual Studio Code)拡張


無停止での更新・デプロイ/Rolling Update

戦略:


複雑な変数の定義と参照


三項演算子/条件によりリソースの作成を制御する


fmt: 自動整形


複数個リソースの参照


workspace: stateを分ける

stateはbackend指定でS3に置けるが、通常default一つしか無い。
dev, stg, prodのように分けてstateを管理できる。
awsのregion毎に分けても良い。


locals: ローカル変数


terraform-landscape: planの結果を見やすく


配列の要素の末尾に文字列を追加

配列の要素の末尾に文字列を結合したい場合がある。

data "aws_iam_policy_document" "s3-r" {
  statement {
    actions = [
      "s3:ListBucket",
    ]

    resources = ["${var.s3_r_bucket_arns}"]
  }

  statement {
    actions = [
      "s3:GetObject",
    ]

    resources = ["${split( ",", "${join("/*,", var.s3_r_bucket_arns)}/*" )}"]
  }
}

Terratest: インフラ自動テストツール

Terraformで起動、チェック実行、破棄までを自動化


タイムアウトの延長

リソースの作成/削除等で、timeoutする場合がある。


alicloud(aliyun alibaba)

中国のalicloud用プロバイダー


ヒアドキュメントでJSON等を綺麗に書く


変数にmap(連想配列)を使う


import block: import対象リソースをコードに書けるように


import: 既存のリソースからtfstateを作成する

terraform state list
terraform state rm <terraform address>
terraform import <terraform address> <resource id>

変数


バージョン変更によるアップグレード方法


lifecycle: 指定リソースの差分を無視する

EBSを追加したり、SGを追加しようとするとEC2を作り直してしまう場合がある。


デバッグ


output: 出力だけを見る

public dns, IP等、後で参照したい情報を出力するのに便利。
refreshまたはapplyした後でしか表示されない。(tfstateファイルの中身を表示しているのでは)

terraform output

# json
terraform output -json

outputで複数リソースの値を出力

Output Variablesでは1つの値しか出力できないようだ。


backend: S3等にtfstateファイルを置く


-target: 指定したリソースだけplan/apply


変数で配列が扱えない


terraformer: 既存のインフラのインポート。GoogleCloudPlatform製


Terraforming: 既存のインフラのインポート

terraform v0.7.0からimport機能が実装されたため、Terraformingは不要かもしれない。

terraform.tfstate や tf形式のソースを生成する [#f45434d2]


複数バージョンの切り替え


不具合


インストール


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2024-09-30 (月) 18:00:13