ナビゲーターガイド:モジュラーインフラストラクチャ構成
注:これは、DigitalOceanSolutionsEngineersが提供するナビゲーターガイドブックの内容の初期リリースバージョンです。 この本の目的は、ビジネス顧客がインフラストラクチャのニーズを計画し、その過程で実用的な例を提供し、技術的なニュアンスと、いくつかの決定を他の決定よりも優れたものにする「理由」を含めるのを支援することです。
この本と付随するコードは、GitHubリポジトリで公開されます。 これは初期のリリースであるため、この本はまだ完成しておらず、リポジトリはまだ公開されていませんが、ご期待ください。
前のセクションでは、TerraformとAnsibleを使用して、リソース(ドロップレット、ロードバランサー、予約済みIP)をプロビジョニングし、WordPressアプリケーションをデプロイしました。
Terraformは、これらのリソースを使用して作成しました main.tf
ファイル。 現在、そのファイル内のすべてのリソースが個別にリストされています。 環境が複雑になるほど、必要なリソースが増え、このファイルは長く複雑になります。 これにより、構成を長期的に管理することがより困難になります。
この補足セクションでは、Terraformモジュールと個別のインフラストラクチャ環境を使用してこの構成を簡素化するいくつかの方法について説明します。 このセクションでは、実行するコードや変更を加える必要はありませんが、実際のセットアップを構築する際には概念が重要です。
Terraformモジュールを理解する
Terraform独自のモジュールの説明を使用するには:
Terraformのモジュールは、グループとして管理されるTerraform構成の自己完結型パッケージです。 モジュールは、Terraformで再利用可能なコンポーネントを作成するため、および基本的なコード編成のために使用されます。
モジュールは、高水準プログラミング言語の関数のように、入力を受け取り、出力を提供できる再利用可能なインフラストラクチャのブロックを作成します。 インフラストラクチャの同様の部分に対してオプションの入力引数を受け入れるモジュールを作成し、それらの入力パラメーターのデフォルト値を設定することもできます。 これにより、構成を整理および簡素化できます。 モジュールの詳細については、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章で詳しく説明します)。
このモジュールは、単一のドロップレットを作成するだけではありません。 ドロップレットタグ、Galeraクラスターノード、ロードバランサー、および予約済みIPを作成します。 テラフォームモジュールは、サービスのコンポーネントまたはサービス全体をパッケージ化するための優れた方法と考えることができます。 また、モジュールにリソースを追加したり、開発中の別のモジュールの入力として使用できるモジュール出力を作成したりできることも意味します。 新しいサービスの追加や、切り離したいサポート機能など、新しいモジュールを作成することが理にかなっている場合は、モジュールに出力を絶対に作成でき、それらは状態の一部として保存されます。 リモート状態を使用している場合、インフラストラクチャのさまざまなコンポーネント間で読み取り専用情報を共有したり、必要な情報を取得する方法を外部サービスに提供したりする場合、モジュール出力は非常に役立ちます。
簡単に言うと、Terraformプランのリソースセクションをレゴブロックと考えると、モジュールは事前に組み立てられたセクションになります。 これは、どこでもレゴブロックを追跡し、場合によっては1つを踏むよりもはるかに優れています。 モジュールは、その苦痛を防ぐのに役立つだけでなく、インフラストラクチャ計画を複雑にするときに、他のモジュールの構成を通知するためにも使用できます。
インフラストラクチャ環境のセットアップ
ほとんどの専門的なプロジェクトでは、開発、ステージング、本番の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スクリプトを間違った場所で誤って実行するのを防ぐのに役立ちます。 さらに一歩進んで、サブディレクトリの別のレイヤーを使用して、各環境のインフラストラクチャのさまざまな部分のファイルを保持できます。
があるこのトピックに関する多くの素晴らしい記事オンライン、そのうちの1つは実際に本になっています Terraform:稼働中 YevgeniyBrikmanによる。
環境でのモジュールバージョン管理の使用
Terraformモジュールは、他の環境に影響を与えることなく変更を加えるのにも役立ちます。 たとえば、これら2つのモジュールを見てください。
ステージング環境用の1つ(たとえば、 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}"
}
1つは実稼働環境用です(たとえば、 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}"
}
それらの間の唯一の違いは、 ref
の最後にあるキー source
行。デプロイするバージョンを指定します。 ステージングでは、 v1.0.8
、そして本番環境では、 v1.0.6
. バージョン管理を使用すると、本番環境にデプロイする前にステージングで変更を加えてテストできます。このようなセットアップにより、それをサポートする構成が簡素化されます。
現在、前のセクションのハンズオンセットアップではリモート状態を使用していません。 第6章では、リモート状態のバックエンド(Consulなど)の使用について説明します。これは、チームで作業するときに重要です。 リモート状態のバックエンドがないと、あなたと別のチームメンバーの両方が同時にインフラストラクチャへの変更を実行し、状態ファイルの競合、停止、または破損を引き起こす可能性があります。
次は何ですか?
インフラストラクチャコードをモジュール化して簡素化する方法と、より安全な開発と展開のために環境を分離する方法を理解したら、テンプレートを作成して展開速度を上げる方法を検討できます。 次の章では、継続的開発ツールを使用してデプロイワークフローを自動化する方法について説明します。これにより、新しいコードを安全かつ迅速にデプロイできます。