今回取り上げる「Terraform」は、IaC(Infurastructure as Code)を実現するOSSツールです。IaCの目的の一つは、GUIなどを使った人手操作による作業ミス発生の防止です。設定内容をコード化(GitHubなどで構成管理)した上で、コードの内容に従ってインフラを自動構築します。

Terraform

Terraformの概要

Terraformと同様に構成管理を行えるOSSツール「Chef」や「Puppet」がOSやミドルウェアを対象に設定するのに対し、Terraformはクラウド上のリソースを対象に設定します。

また、AWS Cloudformationのように特定のクラウドに特化するのではなく、AWS/GCP/Azure/OpenStackなどのマルチプラットフォームに対応しています。

対象 クラウド上のリソースのプロビジョニング OS設定/ミドルのインストール
マルチ Terraform Chef/Puppetなど
特定 CloudFormation/Heatなど -

最新バージョン

2020年12月2日にv0.14がリリースされ、センシティブな変数については値を出力しない設定や、「concise diff」と呼ばれる実行結果の簡素化が実施されました。2021年2月6日時点の最新バージョンはv0.14.6です。

対応プラットフォーム

IaaSやPaaSなどを操作する「provider plugin」により、さまざまなプラットフォームに対応しています。公式サイトで2021年2月7日時点のprovider plugin登録数を確認したところ、763でした。なお、2021年1月16日時点で699だったので、およそ20日で60程度増加と、相当な勢いで増えていることがわかります。

Freatured Providersとして登録されているのは以下6つです。

  • AWS
  • GCP
  • Azure
  • Kubernetes
  • Oracle Cloud Infrastructure
  • Alibaba Cloud

Terraformを触ってみる

事前準備の後、Write - Plan - Applyのステップでインフラを構築します。

# ステップ 内容 対応するコマンド
0 事前準備 terraformコマンドのインストールと構築対象の設定 terraform init
1 Write 設定ファイル(.tf)作成 -
2 Plan Dry Run (構築される内容を事前確認する) terraform plan
3 Apply 実際にインフラを構築する terraform apply

上記のほかには、リソースの依存関係を確認する「terraform graph」などのコマンドがあります。

それでは、順に実施していきましょう。

0. 事前準備

terraformコマンドのインストール、およびterraformコマンドをk8sに向ける設定をします。

◆0-(1) terraformコマンドのインストール

brewコマンドを使ってterraformコマンドをインストールします。
$brew install terraform
==> Downloading https://homebrew.bintray.com/bottles/terraform-0.14.3.big_sur.bo
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/0ede162a28f4d8da53671
######################################################################## 100.0%
==> Pouring terraform-0.14.3.big_sur.bottle.tar.gz
  /usr/local/Cellar/terraform/0.14.3: 6 files, 63.9MB
$terraform
Usage: terraform [global options] <subcommand> [args]

~後略~

◆0-(2) kubernetes providerを設定

「kubernetes provider」を設定し、terraformコマンドをk8sに向けます。設定ファイル(tfファイル)において、「provider」に「[kubernetes]」を設定し、terraform initコマンドを実行します。
$cat main.tf
provider "kubernetes" {}

$terraform init

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/kubernetes...
- Installing hashicorp/kubernetes v1.13.3...
- Installed hashicorp/kubernetes v1.13.3 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

1. Write: 設定ファイル(.tf)作成

Terraformの設定ファイル(tfファイル)は、「HCL(HashiCorp Configuration Language)」と呼ばれるDSL(Domain Specific Language)で記述します(Terraform v0.12以降では、HCL2のシンタックスに従って記載します)。 では、Terraform公式サイトに掲載されているサンプルを参考にtfファイルを書いてみましょう。今回は、次のようにk8sのConfigMapリソースを定義します。
$cat configmap.tf
resource "kubernetes_config_map" "example" {
  metadata {
    name = "my-config"
  }

  data = {
    api_host             = "myhost:443"
    db_host              = "dbhost:5432"
  }

}

2. Plan: Dry Run (terraform plan)

「Dry Run」を実行してみましょう。ConfigMapが1つ作成されることがわかります。
$terraform plan

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # kubernetes_config_map.example will be created
  + resource "kubernetes_config_map" "example" {
      + data = {
          + "api_host" = "myhost:443"
          + "db_host"  = "dbhost:5432"
        }
      + id   = (known after apply)

      + metadata {
          + generation       = (known after apply)
          + name             = "my-config"
          + namespace        = "default"
          + resource_version = (known after apply)
          + self_link        = (known after apply)
          + uid              = (known after apply)
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

3. Apply: 実際にインフラを構築する(terraform apply)

実際にConfigMapを作成してみましょう。「terraform apply」を実行後、入力が求められるので、「yes」と入力します。
$terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # kubernetes_config_map.example will be created
  + resource "kubernetes_config_map" "example" {
      + data = {
          + "api_host" = "myhost:443"
          + "db_host"  = "dbhost:5432"
        }
      + id   = (known after apply)

      + metadata {
          + generation       = (known after apply)
          + name             = "my-config"
          + namespace        = "default"
          + resource_version = (known after apply)
          + self_link        = (known after apply)
          + uid              = (known after apply)
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

kubernetes_config_map.example: Creating...
kubernetes_config_map.example: Creation complete after 0s [id=default/my-config]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
これでConfigMapが作成されました。
$kubectl get configmap
NAME        DATA   AGE
my-config   2      10s

* * *

Kubernetes本体のバージョンは1.20まで進み、Kubernetesの進化は非常に早いと感じます。今回は紹介しませんでしたが、「Terratest」と呼ばれるマニフェストの妥当性をチェックするツールなど、周辺ツールも徐々に増えてきました。 今回の内容を参考に、ジョブやトリガーを構築する「Jenkins」や「CodeBuild」などのCIツール、「ArgoCD」や「Kustomize」といったCD関連ツールとTerraformを組み合わせ、ご自身のDevOps環境を構築してみてください。

著者紹介


正野 勇嗣 (SHONO Yuji ) - NTTデータ 課長

2011年まで開発自動化技術のR&Dに従事。その後、開発プロジェクト支援やトラブルシューティング等に主戦場を移す。「ソースコード自動生成」に加えて、JenkinsやMaven等の「ビルド自動化」、JsTestDriverやSelenium等の「テスト自動化」を扱うようになり、多様化する開発自動化技術動向に興味。

最近は第四の自動化であるInfrastructure as Code等の「基盤自動化」の魅力に惹かれている。開発自動化技術に関する雑誌・記事執筆も行う。3児のパパ。