前のセクションでは、TerraformとAnsibleを使用してリソース(ドロップレット、ロードバランサー、フローティングIP)をプロビジョニングし、WordPressアプリケーションをデプロイしました。

Terraformは、 `+ main.tf +`ファイルを使用してこれらのリソースを作成しました。 現在、そのファイル内のすべてのリソースは個別にリストされています。 環境が複雑になるほど、より多くのリソースが必要になり、このファイルは長く複雑になります。 これにより、構成を長期的に管理するのが難しくなります。

この補足セクションでは、Terraformモジュールと個別のインフラストラクチャ環境を使用して、この構成を簡素化するいくつかの方法について説明します。 このセクションには実行するコードや変更はありませんが、実際のセットアップを構築する際には概念が重要です。

Terraformモジュールについて

Terraform独自のモジュールの説明を使用するには:

_
Terraformのモジュールは、グループとして管理されるTerraform構成の自己完結型パッケージです。 モジュールは、基本的なコード編成だけでなく、Terraformで再利用可能なコンポーネントを作成するために使用されます。
_

モジュールは、高レベルのプログラミング言語の関数のように、入力を受け取って出力を提供できる再利用可能なインフラストラクチャのブロックを作成します。 同様のインフラストラクチャのオプションの入力引数を受け入れるモジュールを作成し、それらの入力パラメーターのデフォルト値を設定することもできます。 これは、構成の整理と簡素化に役立ちます。 モジュールの詳細については、https://www.terraform.io/docs/modules/index.html [Terraformのモジュールドキュメント]をご覧ください。

完成した例については、 `+ main.tf +`ファイルを見てください。 最後のセクションでは、実際にすでにTerraformモジュールを使用しています。

module "sippin_db" {
 source           = "github.com/cmndrsp0ck/galera-tf-mod.git?ref=v1.0.6"
 ...
}

このセクションは、ファイルの先頭にある `+ wp_node +`のリソースブロックと比較できます。これは、コードの行数が多く、追跡が困難です。 モジュールは、リモートgitリポジトリを使用して呼び出されることに注意してください。 ローカルファイルパスを使用できます。ローカルファイルパスを使用すると、迅速な開発とテストが可能になりますが、リモートgitリポジトリを使用すると、環境の分離がさらに一歩進みます。 これは、ステージングや運用など、複数のインフラストラクチャ環境を実行する場合に特に役立ちます。 複数のインフラストラクチャ環境でローカルファイルパスを使用する場合、ステージングのみに影響することを意図した変更を行うことができますが、* prod *で適用を実行し、モジュールファイルパスが共有されている場合、破損する可能性があります何か。 各環境に専用のディレクトリがある場合、スクリプトのコピーを2つ以上維持する必要があり、以前の状態に戻すのはそれほど簡単ではありません。

リモートgitリポジトリを使用し、モジュールのバージョン番号を指定すると、この問題を回避できます。 前述したように、何か問題が発生した場合に既知の作業バージョンに戻すのも簡単になり、インシデントと停止の管理能力が向上します(詳細は第9章で説明します)。

このモジュールは、単一のドロップレットを作成するだけではありません。 Dropletタグ、Galeraクラスターノード、ロードバランサー、およびフローティングIPを作成します。 terraformモジュールは、サービスのコンポーネントまたはサービス全体をパッケージ化する優れた方法と考えることができます。 また、モジュールにリソースを追加したり、開発中の別のモジュールの入力として使用できるモジュール出力を作成したりすることもできます。 新しいサービスの追加や、分離したいサポート機能など、新しいモジュールを作成することが理にかなっている場合、モジュール内に出力を絶対に作成でき、それらは状態の一部として保存されます。 リモート状態を使用している場合、モジュール出力は、インフラストラクチャの異なるコンポーネント間で読み取り専用情報を共有したり、必要な情報を取得する方法を外部サービスに提供したりする場合に非常に役立ちます。

簡単に言えば、Terraformプランのリソースセクションをレゴブロックと考えると、モジュールは事前に組み立てられたセクションになります。 それはどこでもレゴブロックを追跡する必要があり、場合によってはそれを踏むよりもはるかに優れています。 その痛みを防ぐのに役立つだけでなく、インフラストラクチャ計画に複雑さを追加するときに、モジュールを使用して他のモジュールの構成を通知することもできます。

インフラストラクチャ環境のセットアップ

ほとんどのプロのプロジェクトでは、開発、ステージング、プロダクションの3つの異なる環境で作業します。

多くの場合、開発環境はローカルであり、作業中に個別に調整およびテストするためのスペースを提供します。 一方、ステージングおよびプロダクション環境は共有またはパブリックスペースにあり、Terraformなどの自動化プロセスを使用してプロビジョニングされます。

思慮深く計画された展開ワークフローから始めると、頭痛の種を防ぐのに非常に役立ちます。その一部には、環境を相互に分離することが含まれます。 Terraformのワークスペース機能は、環境ごとに `+ terraform.tfstate +`ファイルを分離しますが、リソースを記述するterraformファイルに加えられた変更はそうではありません。 したがって、この機能はマイナーな変更、テスト、および展開を行うための迅速な方法としてはうまく機能する可能性がありますが、サービスの相互分離やチームの分離を必要とする大規模な展開を行う場合には依存しないでくださいそれらを管理します。

次に、ディレクトリを使用して環境の分離を設定する方法を説明するディレクトリツリーの例を示します。

.
├── ansible.cfg
├── bin/
├── environments/
│   ├── config/
│   │   └── cloud-config.yaml
│   │
│   ├── dev/
│   ├── prod/
│   │   ├── config -> ../config
│   │   ├── group_vars
│   │   ├── host_vars
│   │   ├── main.tf
│   │   ├── terraform.tfvars
│   │   ├── terraform-inventory -> ../terraform-inventory
│   │   └── variables.tf
│   │
│   ├── staging/
│   │   ├── config -> ../config
│   │   ├── group_vars
│   │   ├── host_vars
│   │   ├── main.tf
│   │   ├── terraform.tfvars
│   │   ├── terraform-inventory -> ../terraform-inventory
│   │   └── variables.tf
│   │
│   └── terraform-inventory
│
├── site.yml
├── wordpress.yml
│
└── roles/

この種のレイアウトの背後にある重要なロジックは、別々の環境にある類似のコンポーネントに関係するファイルを互いに分離することです。

たとえば、「+ environments 」ディレクトリには、必要な3つの環境(「 dev 」、「 staging 」、および「 prod +」)ごとにサブディレクトリがあります。 この分離は、誤った場所でAnsibleまたはTerraformスクリプトを誤って実行することを防ぐのに役立ちます。 さらに一歩進んで、サブディレクトリの別のレイヤーを使用して、各環境のインフラストラクチャのさまざまな部分のファイルを保持できます。

https://blog.gruntwork.io/a-comprehensive-guide-to-terraform-b​​3d32832baca [このトピックに関する多くのすばらしい記事]がオンラインであり、その1つが実際に_Terraform:Up&Running_ byという本に変わっています。エフゲニー・ブリクマン。

環境でのモジュールのバージョン管理の使用

Terraformモジュールは、他の環境に影響を与えることなく変更を加えることもできます。 たとえば、これら2つのモジュールを見てください。

ステージング環境用(例: + staging / main.tf +):

module "sippin_db" {
 source           = "github.com/cmndrsp0ck/galera-tf-mod.git?ref=v1.0.8"
 project          = "${var.project}"
 region           = "${var.region}"
 keys             = "${var.keys}"
 private_key_path = "${var.private_key_path}"
 ssh_fingerprint  = "${var.ssh_fingerprint}"
 public_key       = "${var.public_key}"
 ansible_user     = "${var.ansible_user}"
}

そして、実稼働環境用のもの(たとえば、 + prod / main.tf +):

module "sippin_db" {
 source           = "github.com/cmndrsp0ck/galera-tf-mod.git?ref=v1.0.6"
 project          = "${var.project}"
 region           = "${var.region}"
 keys             = "${var.keys}"
 private_key_path = "${var.private_key_path}"
 ssh_fingerprint  = "${var.ssh_fingerprint}"
 public_key       = "${var.public_key}"
 ansible_user     = "${var.ansible_user}"
}

それらの唯一の違いは、デプロイするバージョンを指定する「+ source 」行の最後にある「 ref 」キーの値です。 ステージングでは「 v1.0.8 」、プロダクションでは「 v1.0.6 +」です。 バージョン管理を使用すると、実稼働環境にデプロイする前にステージングの変更を行ってテストできます。また、これらのようなセットアップは、それをサポートする構成を簡素化します。

現時点では、前のセクションのハンズオンセットアップではリモート状態を使用していません。 第6章では、チームで作業する際に重要なリモート状態バックエンド(Consulなど)の使用について説明します。 リモート状態のバックエンドがないと、ユーザーと別のチームメンバーの両方がインフラストラクチャの変更を同時に実行し、状態ファイルの競合、停止、破損を引き起こす可能性があります。

次は何ですか?

モジュール化してインフラストラクチャコードを簡素化する方法と、より安全な開発と展開のために環境を分離する方法を理解したら、テンプレートを作成して展開速度を上げる方法を検討できます。 次の章では、継続的な開発ツールを使用して展開ワークフローを自動化する方法について説明します。これにより、新しいコードを安全かつ迅速に展開できます。