Terraform を使用する際に従うべきベスト プラクティスのいくつかについて説明しましょう。
Terraform は、完全なインフラストラクチャを定義およびプロビジョニングするための非常に人気のあるオープンソース IaC (コードとしてのインフラストラクチャ) ツールです。
Terraform は 2014 年に発表されましたが、このツールの採用は世界的に増加しています。組織内にインフラストラクチャを導入するために Terraform を学習する 開発者が増えています。
Terraform の使用を開始した場合は、運用インフラストラクチャのプロビジョニングを改善するためのベスト プラクティスを採用する必要があります。
初心者の場合は、初心者向けの Terraform の記事を参照してください。

構造化
Terraform を使用して大規模な実稼働インフラストラクチャ プロジェクトに取り組んでいる場合は、プロジェクト内で発生する可能性のある複雑さに対処するために、適切なディレクトリ構造に従う必要があります。目的ごとに別々のディレクトリを作成するのが最善です。
たとえば、開発環境、ステージング環境、運用環境で terraform を使用している場合は、それぞれに個別のディレクトリを用意します。
@:~$ tree terraform_project/
terraform_project/
├── dev
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
├── modules
│ ├── ec2
│ │ ├── ec2.tf
│ │ └── main.tf
│ └── vpc
│ ├── main.tf
│ └── vpc.tf
├── prod
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── stg
├── main.tf
├── outputs.tf
└── variables.tf
6 directories, 13 files
一定期間が経過すると、成長するインフラストラクチャの構成は複雑になるため、Terraform 構成も個別にする必要があります。
たとえば、すべての Terraform コード (モジュール、リソース、変数、出力) を
main.tf
ファイル自体の中に記述することもできますが、変数と出力に対して個別の Terraform コードを作成すると、より読みやすく理解しやすくなります。

命名規則
Terraform では、内容を理解しやすくするために命名規則が使用されます。
たとえば、プロジェクト内の異なる環境用に 3 つの異なるワークスペースを作成するとします。したがって、 env1、en2、env3 という名前を付けるのではなく、 dev 、 stage 、 prod と呼ぶ必要があります。名前自体から、各環境に 3 つの異なるワークスペースがあることが明らかです。
リソース、変数、モジュールなどについても同様の規則に従う必要があります。 Terraform のリソース名はプロバイダー名で始まり、その後にアンダースコアとその他の詳細が続く必要があります。
たとえば、AWS でルート テーブルの Terraform オブジェクトを作成するためのリソース名は、
aws_route_table
になります。
したがって、命名規則に正しく従えば、複雑なコードでも理解しやすくなります。

利用可能な公式の Terraform モジュールを使用することを強くお勧めします。すでに存在するモジュールを再発明する必要はありません。時間と労力を大幅に節約できます。 Terraform レジストリには、 すぐに利用できるモジュールが多数あります。必要に応じて既存のモジュールに変更を加えます。
また、各モジュールは、AWS EC2 インスタンスの作成、MySQL データベースの設定など、インフラストラクチャの 1 つの側面のみに集中する必要があります。
たとえば、Terraform コードで AWS VPC を使用したい場合は、次のように使用できます – simple VPC
module "vpc_example_simple-vpc" {
source
= "terraform-aws-modules/vpc/aws//examples/simple-vpc"
version = "2.48.0"
}

最新バージョン
Terraform 開発コミュニティは非常に活発で、新しい機能が頻繁にリリースされます。新しいメジャー リリースが発生した場合と同様に、Terraform の最新バージョンを使用し続けることをお勧めします。最新バージョンに簡単にアップグレードできます。
複数のメジャー リリースをスキップすると、アップグレードが非常に複雑になります。
terraform -v
コマンドを実行して、新しい更新を確認します。
@:~$ terraform -v
Terraform v0.11.14
Your version of Terraform is out of date! The latest version
is 0.12.0. You can update by downloading from www.terraform.io/downloads.html
システム状態のバックアップ
Terraform の状態ファイルは必ずバックアップしてください。
これらのファイルは、インフラストラクチャのメタデータとリソースを追跡します。デフォルトでは、
terraform.tfstate
と呼ばれるこれらのファイルは、ワークスペース ディレクトリ内にローカルに保存されます。
これらのファイルがないと、Terraform はどのリソースがインフラストラクチャにデプロイされているかを把握できません。したがって、状態ファイルのバックアップを作成することが不可欠です。デフォルトでは、状態ファイルのバックアップを保存するために、
terraform.tfstate.backup
という名前のファイルが作成されます。
@:~$ tree terraform_demo/
terraform_demo/
├── awsec2.tf
├── terraform.tfstate
└── terraform.tfstate.backup
0 directories, 3 files
バックアップ状態ファイルを別の場所に保存する場合は、terraform コマンドで
-backup
フラグを使用し、その場所のパスを指定します。
ほとんどの場合、複数の開発者がプロジェクトに取り組んでいます。したがって、状態ファイルへのアクセスを許可するには、
terraform_remote_state
データ ソースを使用して、状態ファイルをリモートの場所に保存する必要があります。
次の例では、S3 にバックアップを取得します。
data "terraform_remote_state" "vpc" {
backend = "s3"
config = {
bucket = “s3-terraform-bucket”
key = “vpc/terraform.tfstate"
region = “us-east-1”
}
}
ロック状態ファイル
複数の開発者が同時に Terraform 構成を実行しようとする複数のシナリオが考えられます。これにより、terraform 状態ファイルの破損やデータ損失が発生する可能性があります。ロック機構はそのような事態を防ぐのに役立ちます。これにより、一度に 1 人だけが Terraform 構成を実行し、競合が発生しないことが保証されます。
ここでは、DynamoDB を使用してリモートの場所にある状態ファイルをロックする例を示します。
resource “aws_dynamodb_table” “terraform_state_lock” {
name = “terraform-locking”
read_capacity = 3
write_capacity = 3
hash_key = “LockingID”
attribute {
name = “LockingID”
type = “S”
}
}
terraform {
backend “s3” {
bucket = “s3-terraform-bucket”
key = “vpc/terraform.tfstate”
region = “us-east-2”
dynamodb_table = “terraform-locking”
}
}
複数のユーザーが状態ファイルにアクセスしようとすると、DynamoDB データベース名と主キーが状態のロックと一貫性の維持に使用されます。
注 : すべてのバックエンドがロックをサポートしているわけではありません。
自己変数を使用する
self
変数は、インフラストラクチャをデプロイする前に変数の値がわからない場合に使用される特別な種類の変数です。
terraform apply コマンドの後にのみデプロイされるインスタンスの IP アドレスを使用したいとします。そのため、インスタンスが稼働するまで IP アドレスはわかりません。
このような場合は、 self 変数を使用します。これを使用する構文は
self.ATTRIBUTE
です。したがって、この場合は、
self.ipv4_address
self 変数として使用して、インスタンスの IP アドレスを取得します。これらの変数は、Terraform 構成の接続ブロックとプロビジョナー ブロックでのみ許可されます。
connection {
host = self.ipv4_address
type = "ssh"
user = var.users[2]
private_key = file(var.private_key_path)
}
爆発範囲を最小限に抑える
爆発範囲は、物事が計画どおりに進まない場合に発生する可能性のある被害の尺度にすぎません。
たとえば、インフラストラクチャにいくつかの Terraform 構成をデプロイしていて、その構成が正しく適用されなかった場合、インフラストラクチャへの損害はどれくらいになりますか。
したがって、爆発範囲を最小限に抑えるために、一度にいくつかの構成をインフラストラクチャにプッシュすることを常にお勧めします。そのため、何か問題が発生した場合でも、インフラストラクチャへのダメージは最小限に抑えられ、迅速に修正することができます。多数の構成を一度に展開することは非常に危険です。
varファイルを使用する
terraform では、拡張子が
<em>.</em>tfvars
のファイルを作成し、
-var-file
フラグを使用してこのファイルを terraform apply コマンドに渡すことができます。これは、terraform 構成コードに含めたくない変数を渡すのに役立ちます。
パスワードや秘密鍵などの変数は、Terraform 構成内やリモートのバージョン管理システムに保存するのではなく、 -var-file を 介してローカルに渡すことを常にお勧めします。
たとえば、terraform を使用して ec2 インスタンスを起動したい場合は、 -var-file を使用してアクセス キーと秘密キーを渡すことができます。
ファイル terraform.tfvars を作成し、このファイルにキーを置きます。
@:~$ gedit terraform.tfvars
access_key = "AKIATYWSDFYU5DUDJI5F"
secret_key = "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"
次に、この var ファイルを terraform コマンドで使用します。
@:~$ terraform apply -var-file=/home//terraform.tfvars
ユーザードッカー
CI/CD パイプラインのビルド ジョブを実行する場合は、Docker コンテナーを使用することをお勧めします。 Terraform は、使用できる公式の Docker コンテナを提供します。 CI/CD サーバーを変更する場合は、コンテナ内のインフラストラクチャを簡単に渡すことができます。
実稼働環境にインフラストラクチャをデプロイする前に、デプロイが非常に簡単な Docker コンテナ上でインフラストラクチャをテストすることもできます。 Terraform と Docker を組み合わせることで、ポータブルで再利用可能、反復可能なインフラストラクチャが得られます。
結論
これらのベスト プラクティスが、より適切な Terraform 構成の作成に役立つことを願っています。より良い結果を得るために、これらを Terraform プロジェクトに実装してください。