この記事は、Data Centre の Technical Solutions Architect である Conor Murphy によるブログ「Introduction to Terraform with Cisco ACI, Part 1」(2021/1/22)の抄訳です。
多くのお客様が、Terraform や Ansible などのサードパーティ製ツールを利用してインフラやアプリケーションを導入し、管理することを検討し始めています。全 5 回のブログシリーズでは、Terraform を紹介し、ACI などのシスコ製品と合わせて使用する方法について解説します。今後数週にわたってブログシリーズで取り上げる内容は次のとおりです。
- Terraform の概要
- Terraform と ACI
- Terraform 設定ファイルの説明
- Terraform リモート状態管理とチームでのコラボレーション
- Terraform プロバイダーの構築方法
コード例
https://github.com/conmurphy/intro-to-terraform-and-aci
Infrastructure as Code
詳細に入る前に、Terraform などのツールのカテゴリである Infrastructure as Code(IaC; コードとしてのインフラストラクチャ)について簡単に説明します。IaC とは、デバイスを設定する際に、CLI や GUI から直接操作するのではなく、テキストファイルに必要な定義を記述して設定する方法です。IaC ツール(Terraform など)が記述されたテキストファイルを読み込むことで、意図した状態が設定されます。
たとえば、システム管理者が、データセンター、クラスタ、ネットワーク、VM を含んだ VCenter/ESXi クラスタを設定する必要があるとします。その際、1 つの方法は、GUI をクリックして必要な各設定を行っていくことです。この方法は時間がかかるだけでなく、プラットフォームで個別の設定を繰り返していくうちに、環境が本来の意図からずれてしまう可能性があります。
意図した設定をファイルに記録し、IaC ツールを使用することで、GUI をクリックしていく必要がなくなるため、導入にかかる時間が短縮されます。
さらに、IaC ツールはインフラ(Vcenter など)をモニタし、ファイル内の意図した設定がインフラと一致していることを確認できます。
次に、Infrastructure as Code のその他のメリットを示します。
導入時間が短縮される。
- 上記を参照してください。
- 重大なエラーが発生した場合に、インフラを迅速に再導入して設定できます。
設定とのずれがなくなる。
- 上記を参照してください。
チームでのコラボレーションが可能になる。
- すべての設定がテキストファイルに定義されているため、チームのメンバーがインフラの設定方法をすばやく理解できます。
説明責任と変更内容が明確になる。
- 設定を記載したテキストファイルは、Git などのバージョン管理ソフトウェアを使用して保存できます。また、2 つのバージョン間の設定の違いも確認できます。
複数の製品を管理できる。
- すべてではないにしても、ほとんどの IaC ツールは、複数の製品やドメインに対応しているため、上記のメリットを 1 つのツールで一元 的に得られます
Terraform は、インフラを安全かつ効率的に構築し、変更やバージョンを管理できるツールです。既存の一般的なサービスプロバイダーや、社内で独自に開発したソリューションも管理できます。
次に、Terraform のコンポーネントをいくつか見ていきます。
設定ファイル
Terraform のコマンドを実行すると、現在のディレクトリで設定ファイルが検索されます。設定ファイルは複数の場合もあります。設定ファイルは、JSON(拡張子 .tf.json)または、Hashicorp Configuration Language(HCL)(拡張子 .tf)のいずれかで記述します。
Terraform の設定ファイルの詳細は、次のリンクから確認できます。
https://www.terraform.io/docs/configuration/index.html
ACI テナント、ブリッジドメイン、サブネットを設定する基本の設定ファイルの例を以下に示します。
provider "aci" {
# cisco-aci password
password = "${var.password}"
# cisco-aci url
url = "${var.apic_url}"
insecure = true
}
resource "aci_tenant" "terraform_tenant" {
name = "tenant_for_terraform"
description = "This tenant is created by the Terraform ACI provider"
}
resource "aci_bridge_domain" "bd_for_subnet" {
tenant_dn = "${aci_tenant.terraform_tenant.id}"
name = "bd_for_subnet"
description = "This bridge domain is created by the Terraform ACI provider"
}
resource "aci_subnet" "demosubnet" {
bridge_domain_dn = "${aci_bridge_domain.bd_for_subnet.id}"
ip = "10.1.1.1/24"
scope = "private"
description = "This subject is created by Terraform"
}
Terraform のコマンド(「コマンド」セクション参照)を実行すると、ACI ファブリックの 3 つのリソース(テナント、BD、サブネット)とそれぞれのプロパティが、設定ファイルに記述されている内容と一致しているかどうかが確認されます。すべて一致している場合、変更は行われません。
設定ファイルと ACI ファブリックに違いがある場合(サブネットが ACI に存在しない場合など)、Terraform は BD 内に新しいサブネットを設定します。テナントと BD がすでに ACI に存在する場合、この 2 つのオブジェクトは変更されません。
Terraform がリソース(ACI ファブリックなど)と設定ファイルを相互に比較し、設定ファイルに一致するようにインフラの作成/更新/削除を行うため、設定とのずれが解消されます。
リソースとプロバイダー
プロバイダーは、API を通じたインタラクションを解釈し、リソースを公開します。プロバイダーは通常、IaaS(Alibaba Cloud、AWS、GCP、Microsoft Azure、OpenStack など)、PaaS(Heroku など)、SaaS(Terraform Cloud、DNSimple、Cloudflare など)のいずれかの形態を取りますが、ここでは Cisco ACI と Intersight について説明します。
リソースはプロバイダー内に存在します。
Terraform のリソースは、ACI テナント、EPG、コントラクト、BD などのインフラオブジェクトを表したものです。
.tf 設定ファイルのリソースブロックでは、特定のタイプのリソースを宣言します。たとえば、「aci_tenant」というリソースにローカル名(「my_terraform_tenant」)を指定します。ローカル名を指定すると、設定ファイルの他の場所で参照できます。
リソースのプロパティは、リソースブロックの波括弧内({ })に指定されます。
以下は、ACI テナントリソースの例です。
provider "aci" {
resource "aci_tenant" "my_terraform_tenant" {
name = "tenant_for_terraform"
description = "This tenant is created by the Terraform ACI provider"
}
この ACI テナント内にブリッジドメインを作成するには、リソース aci_bridge_domain を使用し、必要なプロパティを指定します。
provider "aci" {
resource "aci_bridge_domain" "my_terraform_bd" {
tenant_dn = "${aci_tenant.my_terraform_tenant.id}"
name = "bd_for_subnet"
description = "This bridge domain is created by the Terraform ACI provider"
}
BD は ACI のテナント内に存在するため、両方のリソースをリンクする必要があります。
この場合、BD リソースは、「${terraform_resource.given_name_of_resource.property}」という形式でテナントリソースのプロパティを参照できます。
この仕組みにより、Terraform の設定ファイルに指定されたリソースを簡単に結びつけることができます。
使用できるプロバイダーについては、以下のリストを参照してください。
https://www.terraform.io/docs/providers/index.html
https://www.terraform.io/docs/providers/type/community-index.html
変数とプロパティ
先に説明したように、リソースは「${}」という形式で相互にリンクできます。ユーザが情報を入力する必要がある場合は、次のリンクに記載されている入力変数を使用します。
https://www.terraform.io/docs/configuration/variables.html
多くのリソースでは、ID などのシステムが生成する値も利用できます。これらの値は設定ファイルにはハードコードされず、インフラから取得します。
アクセスする方法は、前述の方法と同じです。次の例では、ID プロパティは aci_tenant リソースではハードコードされていませんが、aci_bridge_domain リソースで参照されています。この ID は、テナントが作成された時にバックグラウンドで生成され、ID を必要とする他のリソースから参照できるようになっています。
provider "aci" {
resource "aci_tenant" "my_terraform_tenant" {
name = "tenant_for_terraform"
description = "This tenant is created by the Terraform ACI provider"
}
resource "aci_bridge_domain" "my_terraform_bd" {
tenant_dn = "${aci_tenant.my_terraform_tenant.id}"
name = "bd_for_subnet"
}
状態管理ファイル
Terraform は、インフラをどのように変更する必要があるかを把握するために、常に環境をトラッキングしています。インフラの状態に関する情報は、デフォルトで「terraform.tfstate」というローカルファイルに保存されます。
注:状態管理ファイルを中央で一元管理することも可能です。これについては後の投稿で説明します。
このファイルを確認するとわかるように、Terraform では、インフラの設定方法が記録されています。plan コマンドまたは apply コマンドを実行すると、意図した設定(.tf ファイル)と現在の状態(.tfstate ファイル)が比較され、差分が抽出されます。
たとえば、config.tf ファイル内にはサブネットが指定されているのに、terraform.tfstate には存在しない場合、ACI に新しいサブネットが設定され、terraform.tfstate が更新されます。
逆の場合も同様です。terraform.tfstate に存在するサブネットが config.tf ファイルに存在しない場合、Terraform はこのサブネットが不要であると見なし、ACI から削除します。
これは非常に重要なポイントです。つまり、何らかの理由で terraform.tfstate ファイルが予期せず変更された場合、望ましくない状態になる可能性があるということです。
以下で実際の例を確認できます。
https://www.youtube.com/watch?v=ix0Tw8uinWs
コマンド
Terraform には多くのコマンドがありますが、知っておいたほうがよい重要なコマンドは次のとおりです。
terraform init
Terraform 設定ファイルがある作業ディレクトリを初期化します。Terraform の新しい設定ファイルを作成するか、バージョン管理システムから既存の設定ファイルを複製した後に実行する最初のコマンドです。このコマンドは何回実行しても問題ありません。
Terraform は、初期化中にプロバイダーへの直接参照および間接参照の設定を確認し、必要なプラグインをロードします。
これは、シスコ インフラストラクチャ プロバイダー(ACI および Intersight)を使用する場合に重要です。
注:HashiCorp 社が配布しているプロバイダーの場合、init コマンドで必要に応じてプラグインが自動的にダウンロードされ、インストールされます。プラグインは、ユーザのプラグインディレクトリに手動でインストールすることもできます。プラグインディレクトリは、ほとんどのオペレーティングシステムでは ~/.terraform.d/plugins にあり、Windows では %APPDATA%\terraform.d\plugins にあります。
https://www.terraform.io/docs/commands/init.html
terraform plan
実行計画の作成に使用します。Terraform は、明示的に無効にしない限り更新を実行し、設定ファイルの意図した状態を実現するために必要なアクションを決定します。
このコマンドは、実際のリソースや状態を変更せずに、一連の変更が意図したとおり実行されるかどうかを確認できる便利な方法です。たとえば、バージョン管理システムに変更をコミットする前に実行すると、想定どおりに動作することを確認できます。
https://www.terraform.io/docs/cli/commands/plan.html
terraform apply
terraform apply コマンドは、設定で意図した状態にするために必要な変更を、実際に適用する際に使用します。また、terraform plan コマンドによって生成された、事前に確認済みの一連のアクションを実行することもできます。
https://www.terraform.io/docs/commands/apply.html
terraform destroy
Terraform が管理するインフラが破棄されます。破棄する前には確認が求められます。
https://www.terraform.io/docs/commands/destroy.html
参考資料
- https://www.terraform.io/intro/index.html
- https://www.terraform.io/docs/providers/index.html
- https://learn.hashicorp.com/
- https://developer.cisco.com/site/aci/