エンジニアリング

全手順を自動化:Terraform+Ansible+Elastic Cloud Enterprise

前回の記事、「Automating the installation of Elastic Cloud Enterprise with Ansible(AnsibleでElastic Cloud Enterpriseのインストールを自動化する)」に続いて、本記事ではTerraformでクラウドプロビジョニングの自動化を拡張する方法をご紹介します。前回、Ansibleを使用してAWSの3つのアベイラビリティゾーンにElastic Cloud Enterprise(ECE)をデプロイ、および設定する方法を説明しました。しかしこの方法では、基盤となるEC2インスタンスのプロビジョニングと、セキュリティグループの設定はすべて手動で行う必要がありました。

本記事では、Terraformを使ってメソッドを改良し、EC2インスタンス、およびセキュリティグループのプロビジョニングと設定を自動化する方法を実演します。さらにこの手法で、インストール、設定、および前回作成したAnsible Playbookの実行を自動化してみます。自動化には多くのメリットがあります。

ところで、Terraformとは何でしょうか。ジェネシス計画のテラフォーミングに関する話かと思った人が筆者以外にもいるかもしれません。一応断っておくと、その件は関係ありません。HashiCorp(開発元)によれば、Terraformとは高水準の設定を使う、インフラの開発・変更・バージョン管理用ツール、つまりInfrastructure as Code(コードとしてのインフラ)です。インフラの立ち上げ、実行、設定に必要なすべてのものを、バージョン管理可能で、プログラム的にCRUDできるテキストファイルに置ける、というメリットをはじめ、このツールが便利である理由は数多くあります。

本記事ではクラウドプロバイダーとしてAWSを取り上げる形でご説明しますが、Terraformはいずれのクラウドプロバイダーのプロビジョニング・管理リソースとしても使用できます。詳しくは、同社の主要クラウドプロバイダーリストおよび、(“主要”が外れた)クラウドプロバイダーリストをご覧ください。GCPで使用する場合の具体例はGitHubのこちらのrepoでご覧いただくことができます。

最後に、前回と同様、本記事は基本的なデモンストレーションを通じて、小規模な概念実証や、開発環境に最適なECE環境の作成手順をご紹介しています。本番環境向けのデプロイでは、インスタンスグループやロードバランサー、他の高可用構成物を使用する必要がありますが、本記事ではいずれの設定も省略されている点にご留意ください。本番用のプランニングとデプロイについて詳しくは、Elastic Cloud Enterpriseプランニングドキュメントをご参照ください。

では、始めようか。

タスク

前回同様、ECEドキュメントの小規模なベースラインインストール例に沿って進めますが、各タスクの内容は大きく異なります。

  1. Terraformをインストールする
  2. インフラを定義する
  3. 実行する
  4. ドヤ顔する

Terraformをインストールする

HashiCorpのドキュメントに沿ってインストールを実施します。また、前回の記事の手順でインストールしたAnsibleも必要です。まだインストールされていない場合は、Ansibleドキュメントをご参照ください。ちょっと頼りないキーボードのMacbook Proを使う筆者の場合は、次の通りです。

> brew install terraform
> brew install ansible

筆者が使用した構成はTerraform version 0.12と互換性があり、この点は重要です。具体的には、0.12.19を使用しました。

インフラを定義する

このタスクの手順は次の通りです。

  1. 筆者が使用したTerraformのconfigを使ってブートストラップする。
  2. ファイルを閲覧し、作業の概要を理解する。
  3. ユーザー固有の変数を設定する。

Terraformのconfigをブートストラップする

はじめにご説明した通り、Terraformは設定ファイルを介してインフラをプロビジョニングする手段です。したがって、大量のconfigファイルを扱うことになります。レポジトリをコピーするか、GitHubのレポジトリにある例からファイルをダウンロードして手っ取り早く進めることができます。必要な手順はすべて、これらのファイルを通じて実行できます。

前回もお伝えしましたが、ご紹介している手順はCLIを主に使用するユーザー向けです。これは「マウスでここをクリックします」式の手順説明の方が大変であるためですが、ご了承くださるようお願いいたします。

手順
  1. 例示のレポジトリをコピー、またはダウンロードします。
    > git clone https://github.com/elastic/examples.git
    	
  2. 保存した場所を指定してファイルを参照します。
    > cd /workspace/github/elastic/examples
    	
  3. ECE AWS Terraformの例をナビゲートします。
    > cd Cloud\ Enterprise/Getting\ Started\ Examples/aws/terraform
    	
  4. テキスト編集の(ため、心の)準備をします。

ファイルを閲覧する

今、以下のファイルが手元にあるはずです。閲覧してみましょう。

terraform.tfvars.exampleterraform.tfvarsにリネームした後、必要に応じて機密を設定したり、variables.tfの変数を上書きする主たるファイルです。
variables.tf数多くの変数があり、目を通しておく必要があります。
provider.tfAWSへの接続方法を指定するTerraform configです。
servers.tf望ましいAMIを検出し、インスタンスをデプロイするほか、インスタンスメタデータを捉えてAnsibleで使えるようにするTerraform configです。
networking.tfインターネットゲートウェイ、ルーティングテーブル、サブネット、セキュリティグループなど多数のAWSネットワーク設定を実行するTerraform configです。
main.tfAnsibleスクリプトをローンチし、重要なアウトプットの一部を収集するTerraform configです。
ansible-install.shTerraformが修正し、設定を呼び出して、ECEのロールでAnsibleを実行するスクリプトです。

変数を設定する

皆さんの環境できちんと動作させるために、いくつかの異なる変数を設定します。

  • 作成したすべてのAWSリソースでタグ付けされるプロジェクト名
  • 基盤となるインスタンスに、自分だけがSSHアクセスを持つようにするためのIP。オープンにしておきたい場合は、0.0.0.0/0に設定しても構いません
  • Terraformがプロビジョニングを行うためのAWSへのアクセス資格情報

AWSのaccess/secretキーペアがない場合は、AWSドキュメントに従って作成することができます。

補足:variables.tfは、EC2インスタンスにSSHでログインするために使用するパブリックキーとプライベートキーファイルの場所を定義します。SSHキーがないという方は、googleで検索してみてください。DigitalOcean社がLinux/OSXおよびWindows向けに、基本的でわかりやすい説明を提供しています。

手順
  1. terraform.tfvars.exampleを、terraform.tfvarsにリネームします。
  2. terraform.tfvarsファイルに、以下の変更を加えます。
    1. すべてのAWSリソースを特定するために使用するproject_nameを設定します。
    2. trusted_networkを、CIDR notationの自身のIP、またはお好みの範囲に設定します。
    3. 自身の情報を使用してaws_access_keyaws_secret_keyを設定します。
    4. (任意)aws_regionpublic_key、ないしprivate_keyを上書きします。

AMIと、EC2インスタンスタイプ設定の2点は、変更しないでください。理由はいくつかありますが、主に立ち上げ手順の複雑さを軽減するためです。前回と同じく、CentOS 7 AMIからi3.xlargeインスタンスを3つデプロイしたいと思います。

  • Terraformが適切なAMIを確実に見つけることができるよう、Terraformにさまざまなメタデータを提供できます。今回は、名前パターン、所有者ID(centos.org)、仮想化タイプを使用しました。名前パターンと所有者IDはvariables.tfに設定できますが、別のAMI(例:Ubuntuのもの)を選択すると、remote_userに別の値が必要となる可能性がある点に注意してください。
  • インスタンスタイプを変更すると、他の部分も変更が必要です。i3はTerraformの設定に記載された特定のOSデバイス名と設定情報で、ローカルに接続されたNVMeドライブを利用します。別のインスタンスを使用し、EBSボリュームを接続する場合は、servers.tfを変更して適切にマップする必要があります。詳しくは、Terraformドキュメントを参照してください。

筆者がAMIとEC2インスタンスタイプに使用した設定は、variables.tfで確認できます。

# AWS MarketplaceにあるAMIの名前
variable "aws_ami_name" {
  default = "CentOS Linux 7 x86_64 HVM*"
}
# AMIの所有者
variable "aws_ami_owner" {
  default = "679593333241" # centos.org
}
# インスタンスにログインし、インストールを実施するユーザー
# これは使用するAMIに依存するため、確実に同期させますたとえば、Ubuntu AMIはubuntuユーザーを使用します
variable "remote_user" {
  default = "centos"
}
# ECEインスタンスタイプ
variable "aws_instance_type" {
  default = "i3.xlarge"
}
# ECEが使用するnon-rootボリュームのデバイス名
# i3インスタンスでは、nvme0n1です
# 別のインスタンスタイプを使用する場合はこの値も異なり、servers.tfのリソース定義も変更する必要がある可能性があります
variable "device_name" {
  default="nvme0n1"
}

実行する

手順はほぼ終わりました。早いと思いませんか?デフォルトで進めてきて、configファイルの調査にそれほど時間を取られなかった場合、Terraformをインストールして、ファイルをいくつかコピーして、いくつか変数を入れただけ、という状態のはずです。これだけで実行のステップに進むことができます。

手順
  1. Terraformを初期化します。
    > terraform init
    	
  2. 苦労して構築したconfigを適用します。
    > terraform apply
    	

はい、手順は以上です。

しばらく待つと、以下のようなアウトプットが現れ、ECE管理者コンソール用のURLと管理者パスワードを取得できます。

null_resource.run-ansible (local-exec):TASK [ansible-elastic-cloud-enterprise : debug] ********************************
null_resource.run-ansible (local-exec): ok: [ec2-52-70-7-3.compute-1.amazonaws.com] => {
null_resource.run-ansible (local-exec):     "msg":"Adminconsole is reachable at: https://ec2-35-175-235-131.compute-1.amazonaws.com:12443"
null_resource.run-ansible (local-exec): }
null_resource.run-ansible (local-exec):TASK [ansible-elastic-cloud-enterprise : debug] ********************************
null_resource.run-ansible (local-exec): ok: [ec2-52-70-7-3.compute-1.amazonaws.com] => {
null_resource.run-ansible (local-exec):     "msg":"Adminconsole password is: yI6ClXYNQ5LGiZlBuOm94s8hGV5ispQS24WVfL5fE9q"
null_resource.run-ansible (local-exec): }
null_resource.run-ansible (local-exec):TASK [ansible-elastic-cloud-enterprise : include_tasks] ************************
null_resource.run-ansible (local-exec): skipping: [ec2-52-70-7-3.compute-1.amazonaws.com]
null_resource.run-ansible (local-exec):PLAY RECAP *********************************************************************
null_resource.run-ansible (local-exec): ec2-34-229-205-85.compute-1.amazonaws.com : ok=68   changed=37   unreachable=0    failed=0    skipped=7    rescued=0    ignored=1
null_resource.run-ansible (local-exec): ec2-35-175-235-131.compute-1.amazonaws.com : ok=68   changed=29   unreachable=0    failed=0    skipped=8    rescued=0    ignored=1
null_resource.run-ansible (local-exec): ec2-52-70-7-3.compute-1.amazonaws.com : ok=68   changed=37   unreachable=0    failed=0    skipped=7    rescued=0    ignored=1
null_resource.run-ansible:Creation complete after 16m50s [id=7701810896203834102]
Apply complete!Resources:1 added, 0 changed, 1 destroyed.
Outputs:
ece-instances = [
  [
    "ec2-35-175-235-131.compute-1.amazonaws.com",
    "ec2-34-229-205-85.compute-1.amazonaws.com",
    "ec2-52-70-7-3.compute-1.amazonaws.com",
  ],
]
installed-ece-url = https://ec2-35-175-235-131.compute-1.amazonaws.com:12443

開いて、立ち上げてみることをおすすめします。大丈夫。問題が生じても、消して作り直せばよいだけです:

> terraform destroy
> terraform apply

補足:TLSに自己署名証明書を使用しているため、管理者コンソールにアクセスを試みると、ブラウザーに警告が表示されます。適切に署名した証明書を使用するよう、いつでもECEを設定することができます。詳しくは、ドキュメントでご確認ください。

ドヤ顔する

Jazz hands

前回の手順に比べて、かなり手間と時間が軽減されていると感じていただけましたら幸いです。AWSコンソールと、リソースをデプロイ、設定し、安全に保つために従来実施していた約38の手順をうまく回避しました(数えてみたところ、今回の手順数は10です)。

ここからは思いのままに暴れてください。クラウドなんて朝飯前です。ECEをいじって、クラスターを立ち上げたりアップグレードしたり、サイズを変更したりできます。簡単で、快適なECEをお楽しみください。