リリース/構成管理: Terraform編 – 「若手エンジニアのためのDevOps入門」(7)

こんにちは、山本和道です。
本記事は連載「若手エンジニアのためのDevOps入門」の第7回です。

第1回 インフラエンジニアにとってのDevOps
第2回 Webアプリでの開発環境構築
第3回 バージョン管理システム
第4回 継続的インテグレーション/デリバリー
第5回 DevOpsのための道具箱: APIを使いこなす
第6回 リリース/構成管理: 概要
第7回 リリース/構成管理: Terraform編

第6回はリリース/構成管理の概要について扱いました。今回は実践編としてTerraformを用いて実際にインフラを構築してみます。

クラウド上のインフラ構築のためのツール

最初にインフラの構築を行うためのツールにはどのようなものがあるか見ておきます。

各クラウドプラットロームが提供する専用ツール

まず、各クラウドプラットフォームではそれぞれが専用のツールを提供していることが多いです。例えば以下のようなツールがあります。

  • AWS: Cloud Formation
  • Azure: Resource Manager
  • GCP: Deployment Manager

これらのツールはそれぞれのプラットフォーム専用のツールとなっており、専用ツールならではの幅広い対応範囲や細かな制御が行えることが特徴となっています。各プラットフォーム純正ツールであることから新しい機能への対応なども素早く確実に利用できるツールといえます。

複数のプラットフォームに対応しているTerraform

対して今回取り上げるTerraformはHashiCorp社の主導により開発されているオープンソースのツールです。

Terraformは定義ファイルのパースや定義されたリソースの依存関係の解決などのコア機能を提供する部品と、実際にクラウドなどのインフラを操作するプロバイダーと呼ばれる部品に分かれており、各プラットフォーム向けにプロバイダーを実装することで拡張可能となっています。

プロバイダーの実装はすでに多岐にわたっており、HashiCorp社の主導でテスト/リリースを行うビルトインプロバイダーや、コミュニティーにより開発されているコミュニティープロバイダーを含めると、主要なクラウドプラットフォームは十分にカバーされています。

AWS/Azure/GCPをはじめ、大小様々なクラウドプラットフォーム(等)に対応されていることがTerraformの強みの一つです。

Terraformは複数のプラットフォームに対し統一したワークフローを提供してくれる

Terraformは複数のプラットフォームに対応していますが、一つの定義ファイルで全てのプラットフォームをカバーしてくれるわけではありません。例えばAWS/Azure上にサーバを構築したい場合は、AWS/Azureそれぞれ用に定義ファイルを書く必要があります。

各プラットフォーム向けに定義ファイルを書くのであれば各プラットフォーム専用ツールを使った方が良いのではないかと思うかもしれませんが、Terraformの狙いは定義ファイルの統一ではなく、Terraformを使うことによるワークフローの統一にあります。

例えばインフラをコード化しGitHubで管理、CIサーバでTerraformを実行することでインフラ構築を行う場合を考えてみます。

まず、インフラの変更を行う場合、どのような変更が行われるか確認してから適用することが多いでしょう。GitHubを利用する場合はインフラコードの変更を行うプルリクエストが作成された際にどのようなインフラの変更が行われるか確認できるとレビューも行いやすいと思います。

これを実現するには、

  • GitHubのプルリクエストを契機にCIサーバでのジョブを起動
  • CIサーバではインフラ構築ツールを実行し、インフラにどのような変更が行われるか出力する(dry-run機能などを利用)
  • その結果をレビューアに通知しレビューしてもらう

というようなワークフローになるかと思います。

Terraformを用いない場合、各ツールごとにCIサーバのセットアップ方法が異なるためそれぞれのツールに応じたセットアップが必要となります。また、インフラの変更差分については各ツールの出力形式が異なるため、差分確認の際に見るべきポイントが異なることになります。

もしインフラの変更差分をレビューしやすいように加工(例えばテキスト形式の変更差分をグラフィカルに表示するなど)している場合はその部分もツールごとに個別対応が必要となります。

Terraformを用いることで、同一のツールで様々なプラットフォームに対応でき、変更差分の出力形式も統一されるため、どのプラットフォームに対しても統一したワークフローを取ることができます。

これにより、単純にツールを再利用するのではなく、同一のワークフローを様々なプロジェクトで再利用できるという点がTerraformの強みだと思います。

実践: Terraformを利用する

さくらのクラウドの「リソースマネージャ」でTerraformを体験

それでは実際にTerraformでのインフラ操作を体験してみます。

TerraformはGo言語で書かれたコマンドラインツールとなっており、インストールは実行ファイルをダウンロードしてくるだけと非常に手軽に扱えますが、実際にクラウド上のリソースを操作するにはそれぞれの環境ごとにAPIキーやトークンなどで認証を行うための設定をしなければなりません。

今回は手軽に実行するためにさくらのクラウドの「リソースマネージャ」という機能を利用します。「リソースマネージャ」はさくらのクラウドのコントロールパネルからインフラ定義コードを登録することで、定義に沿ったインフラ構築を行ってくれるサービスです。

内部的にTerraformが利用されておりAPIキーの設定などの認証情報を簡単に設定できるようになっています。ブラウザでコントロールパネルの操作を行うだけで利用できるため、Terraformの操作を手軽に体験するのに便利です。

なお、当記事ではTerraformでのインフラ構築を体験してみることに主眼を置いており、細かなコードの書き方やTerraformの操作方法には触れません。DevOpsプロセスに組み込むなど本格的に利用したい場合はTerraform公式サイトのドキュメントなども参照してください。

今回構築するインフラの構成

今回はさくらのクラウド上に1台のサーバを構築してみます。

さくらのクラウドではサーバ構築の際には以下のような項目を選択/決定する必要があります。

  • ゾーン(東京第1/石狩第2/サンドボックス)
  • サーバプラン(仮想コア数/メモリサイズ)
  • 接続するディスク(新規作成/既存ディスク/ディスクレス)
  • ディスクにインストールするOS(コピー元アーカイブ)
  • ネットワークへの接続方法
  • 管理ユーザーのパスワード
  • サーバの名称/ホスト名

今回は以下のような構成でサーバ構築を行います。

  • ゾーン: サンドボックス
  • 仮想コア数: 1コア
  • メモリサイズ: 1GB
  • ディスク: 20GB/SSDを新規作成
  • OS : CentOS7
  • ネットワーク: インターネットに接続

それでは早速この構成をコード化してみます。

インフラのコード化

Terraformでは作成するインフラを「リソース」と呼ばれる単位で定義していきます。リソースは各プロバイダーごとに異なっており、どのようなリソースがあるのかは各プロバイダーのドキュメントに記載されています。

さくらのクラウドの場合は以下のサイトでドキュメントを公開しています。

> Terraform for さくらのクラウド ドキュメント

コード化の際はドキュメントを参照し、どのリソースをコードで定義すれば良いのかを調べます。

今回の構成の場合は以下のリソースを定義することになります。

  • サーバ: "sakuracloud_server"
  • ディスク: "sakuracloud_disk"
  • OS: "sakuracloud_archive"

これらのリソースの骨格のみ定義したコードは以下のようになります。

コードの定義(骨格のみ)

resource sakuracloud_server "server" {
 # ここにサーバの設定を記載
}

resource sakuracloud_disk "disk" {
 # ここにディスクの設定を記載
}

data sakuracloud_archive "os" {
 # ここにOSの設定を記載
}

次にこのコードに対し仮想コア数やメモリサイズといった必要な構成の設定を記載していきます。ここでもドキュメントを参照してどのような項目が設定可能なのか確認の上でコードを記載していきます。

今回の構成の場合は以下のようなコードになります。

コードの定義

resource sakuracloud_server "server" {
  name = "server"                         # サーバ名
  core = 1                                # 仮想コア数
  memory = 1                              # メモリサイズ
  nic = "shared"                          # ネットワーク
  disks = ["${sakuracloud_disk.disk.id}"] # 接続するディスク
}

resource sakuracloud_disk "disk" {
  name = "disk"       # ディスク名
  plan = "ssd"        # プラン(SSD or HDD)
  size = 20           # ディスクサイズ
  hostname = "server" # ホスト名
  password = ""       # パスワード

  source_archive_id = "${data.sakuracloud_archive.os.id}" # コピー元アーカイブ(OS)
}

data sakuracloud_archive "os" {
  os_type = "centos" # OS種別
}

これでインフラをコード化することができました。

今回はここまでのコード化に留めますが、コードを変更/再利用しやすいように変数を切り出したりモジュール化することも可能です。必要に応じてTerraformのドキュメントなどを参照してください。

インフラの構築

次に作成したコードを用いてさくらのクラウドの「リソースマネージャ」でインフラを構築してみます。

まずはさくらのクラウドのコントロールパネルにログインし、APIキーの発行を行います。ログイン後、左の「APIキー」メニューから発行が行えます。リソースマネージャではインフラの作成/削除を行う必要があるため、アクセスレベルとして「作成・削除」を選択しておいてください。

次にリソースマネージャの作成を行います。

コントロールパネルのトップページの「リソースマネージャ」メニューから作成が行えます。

リソースマネージャ作成時はゾーンとして「サンドボックス」を選択し、APIキーに先ほど発行したAPIキーを選択しておきます。

次に作成したリソースマネージャの詳細画面から先ほど作成したコードの登録を行います。

右上の「tffileを変更」ボタンからコードの入力画面へ移動しコードを登録してください。

これでインフラ構築のための準備が整いました。次にインフラ構築を行います。右上の「コマンド」から「計画/反映」を実行することで登録したコードを元にインフラ構築が行われます。

しばらく待つとサンドボックスゾーンにサーバが一台作成されているはずです。コントロールパネルにて確認してみてください。

これでインフラ構築が行えました。今回は非常に単純な例でしたが、様々なリソースを組み合わせることでより複雑な構成でも構築可能です。リソースマネージャで利用できる構成例/コードは以下のサイトで公開されていますので興味のある方はぜひご覧ください。

> リソースマネージャ: テンプレート

最後に、リソースマネージャの詳細画面から「破棄」を実行しておいてください。

まとめ

今回はインフラ構築のためのツールとしてTerraformの紹介、Terraformでのインフラのコード化、リソースマネージャ(Terraform)を用いてのインフラ構築の実習を行いました。

Terraformは一度コード化してしまえば繰り返し構築作業を行う際も素早く構築でき、DevOpsプロセス全体としての速度向上も見込めるためインフラエンジニアとしてぜひとも押さえておきたいツールだと思います。ぜひ実際にコードを書いてインフラ構築を体験してみてください。

また、今回はサーバの構築を行いましたが、サーバの設定を変更したり任意のアプリケーションを配置するといった作業は行なっていません。次回はこの辺りの設定を行うためのツールであるAnsibleやPackerについて取り上げます。