1. ホーム
  2. continuous-integration

[解決済み] Terraformを使用する際のベストプラクティス [終了しました]。

2022-07-22 14:08:44

質問

インフラをterraformにスワップしている最中です。 テラフォームのファイルや状態を実際に管理するためのベストプラクティスは何でしょうか? 私はそれがコードとしてのインフラストラクチャであることを理解し、私は.tfファイルをgitにコミットします。それはS3などのどこかに置くべきですか?私は最終的にCIがこれらすべてを管理することを望んでいますが、それははるかに拡張されており、ファイルのための可動部分を把握する必要があります。

私は本当に、そこにいる人々が実際に生産でこのタイプのものをどのように利用するかを見たいと思っています。

どのように解決するのですか?

私も既存のAWSインフラをTerraformに移行している状態なので、開発しながら回答を更新することを目指します。

私はこれまでTerraformの公式サイトである の例 に大きく依存し、何度も試行錯誤を繰り返しながら、不明な部分を改善してきました。

.tfstate ファイル

Terraformの設定は、異なるインフラストラクチャ上の多くのボックスをプロビジョニングするために使用され、それぞれが異なる状態を持つことができます。複数の人によって実行されることもあるので、この状態は(S3のような)一元管理された場所にあるべきですが ではなく git ではありません。

これはTerraformを見ると確認できます。 .gitignore .

デベロッパーコントロール

私たちの目的は、完全な監査 (git log) と変更 (pull request) の健全性をチェックする能力を維持しながら、開発者にインフラのより多くの制御を提供することです。このことを念頭に置いて、私が目指している新しいインフラストラクチャのワークフローは次のとおりです。

  1. puppet などの再利用可能なモジュールを含む、共通の AMI の基本基盤。
  2. Terraformを使用してDevOpsがプロビジョニングするコアインフラストラクチャ。
  3. 開発者は必要に応じてGitでTerraformの設定を変更します(インスタンスの数、新しいVPC、リージョン/アベイラビリティゾーンの追加など)。
  4. Gitの設定をプッシュし、プルリクエストを送信し、DevOpsチームのメンバーがサニティチェックを行います。
  5. 承認されたら、CIにwebhookを呼び出してビルドとデプロイを行う(現時点では複数の環境をどのように分割するかは不明)

編集1 - 現状をアップデート

この回答を開始して以来、私は多くの TF コードを書き、私たちの状況についてより快適に感じています。途中でバグや制限にぶつかることもありましたが、これは新しく、急速に変化するソフトウェアを使用する際の特徴であると受け止めています。

レイアウト

私たちは、それぞれが複数のサブネットを持つ複数の VPC を持つ複雑な AWS インフラストラクチャを使用しています。これを簡単に管理する鍵は、リージョン、環境、サービス、所有者を包括する柔軟な分類法を定義することで、私たちのインフラのコード(テラフォームとパペットの両方)を整理するために使用することができました。

モジュール

次のステップは、テラフォームモジュールを格納するための単一のgitリポジトリの作成です。モジュールのトップレベルのディレクトリ構造はこのようになっています。

tree -L 1 .

結果

├── README.md
├── aws-asg
├── aws-ec2
├── aws-elb
├── aws-rds
├── aws-sg
├── aws-vpc
└── templates

それぞれ、いくつかのまともなデフォルトを設定しますが、私たちの "glue" によって上書きできる変数としてそれらを公開します。

接着剤

私たちは2番目のリポジトリに glue があり、上記のモジュールを利用しています。これは、私たちのタクソノミーのドキュメントに沿ってレイアウトされています。

.
├── README.md
├── clientA
│   ├── eu-west-1
│   │   └── dev
│   └── us-east-1
│       └── dev
├── clientB
│   ├── eu-west-1
│   │   ├── dev
│   │   ├── ec2-keys.tf
│   │   ├── prod
│   │   └── terraform.tfstate
│   ├── iam.tf
│   ├── terraform.tfstate
│   └── terraform.tfstate.backup
└── clientC
    ├── eu-west-1
    │   ├── aws.tf
    │   ├── dev
    │   ├── iam-roles.tf
    │   ├── ec2-keys.tf
    │   ├── prod
    │   ├── stg
    │   └── terraform.tfstate
    └── iam.tf

クライアントレベルの内部では、AWSアカウント固有の .tf ファイルがあり、グローバルリソース(IAMロールなど)をプロビジョニングします。次にリージョンレベルでEC2のSSH公開鍵があり、最後に私たちの環境( dev , stg , prod など)には、VPCの設定、インスタンスの作成、ピアリング接続などが保存されています。

サイドノート おわかりのように、私は上記の自分のアドバイスに反して terraform.tfstate をgitに保存しています。これはS3に移行するまでの一時的な措置ですが、現在唯一の開発者である私には好都合です。

次のステップ

これはまだ手動プロセスで、Jenkins にはまだ入っていませんが、かなり大規模で複雑なインフラストラクチャを移植しており、今のところ順調です。私が言ったように、いくつかのバグがありますが、うまくいっています!

編集 2 - 変更点

この最初の回答を書いてから約1年が経ち、Terraformの状態も私自身の状態も大きく変化しています。私は今、Azureクラスタを管理するためにTerraformを使う新しい職場にいて、Terraformは現在では v0.10.7 .

状態

人々は私に繰り返し、国家は ではない をGitに入れるべきだと何度も言われましたが、そのとおりです。私たちは、開発者のコミュニケーションと規律に依存する2人のチームで、暫定的な措置としてこれを使用しました。より大規模で分散したチームでは、現在、S3 のリモート状態を完全に活用するために ロック を利用しています。理想的には、クラウド プロバイダーを横断するために、これは現在 v1.0 の consul に移行される予定です。

モジュール

以前は内部モジュールを作成し、使用していました。これは現在でもそうですが、 Terraformレジストリ の出現と成長により、少なくともベースとしてこれらを使用するようにしています。

ファイル構成

新しいポジションでは、2つのinfx環境だけで、よりシンプルなタクソノミがあります。 devprod . それぞれ独自の変数と出力を持っており、上で作成したモジュールを再利用しています。また remote_state プロバイダーは、環境間で作成されたリソースの出力を共有するのにも役立ちます。私たちのシナリオは、グローバルに管理された TLD への異なる Azure リソース グループのサブドメインです。

├── main.tf
├── dev
│   ├── main.tf
│   ├── output.tf
│   └── variables.tf
└── prod
    ├── main.tf
    ├── output.tf
    └── variables.tf

企画

分散したチームでの追加の課題として、私たちは常に terraform plan コマンドの出力を常に保存するようにしました。コマンドの間に何らかの変更を加えるリスクなしに、何が実行されるかを検査し知ることができます。 planapply のステージがあります (ロックはこれに役立ちますが)。この計画ファイルは、プレーンテキストのquot;secret"変数を含む可能性があるため、忘れずに削除してください。

全体として、私たちは Terraform にとても満足していますし、追加された新しい機能によって学び、改善し続けています。