PackerとTerraformを使った完全なDevOpsデプロイメントの作成

**Packer**と**Terraform**を使用すると、**Alibaba Cloud**上のアプリケーションのリリースサイクルとインフラストラクチャの更新を維持するための完全な**DevOps**デプロイメントを簡単に作成することができます。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/how-to-deploy-apps-effortlessly-with-packer-and-terraform_593894)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

[Alibaba Cloud Tech Share](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.2e712acdjDCZyR)執筆者、Alberto Roura。[Tech Share](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.2e712acdjDCZyR)は、技術的な知識やベストプラクティスをクラウドコミュニティ内で共有することを奨励するAlibaba Cloudのインセンティブプログラムです。

Alibaba Cloudは、[DevOpsに関する非常に端正なホワイトペーパー](http://alicloud-common.oss-ap-southeast-1.aliyuncs.com/DevOps_Solution/Alibaba%20Cloud%20DevOps%20Solution%20White%20Paper_v2.pdf?spm=a2c65.11461447.0.0.2e712acdjDCZyR&file=Alibaba%20Cloud%20DevOps%20Solution%20White%20Paper_v2.pdf)を公開しており、読んでみると非常に興味深いものがあります。それによると、「DevOpsとは、インフラストラクチャを管理するためのアジャイル原則の単純な実装を超えたモデルです。John WillisとDamon Edwardsは、CAMS（Culture, Automation, Measurement, and Sharing）という用語を使ってDevOpsを定義しており、DevOpsは開発チームと運用チームのコラボレーションを促進しようとしています」と述べています。

これは、大まかに言えば、ソフトウェア開発とインフラ管理の両方をつなぐことを目指すチームに新しい役割やマインドセットがあることを意味しています。この役割は、両方の世界の知識を必要とし、現在重要性を増しているクラウドパラダイムを活用するものです。しかし、DevOpsの実践は大企業に限ったことではありません。開発者として、私たちは日常のタスクにDevOpsを簡単に取り入れることができます。このチュートリアルでは、いくつかの設定ファイルを使うだけで簡単にデプロイメント全体をオーケストレーションすることができることを見ていきます。このチュートリアルでは、Alibaba Cloud [Elastic Compute Service (ECS) ](https://www.alibabacloud.com/product/ecs?spm=a2c65.11461447.0.0.2e712acdjDCZyR)インスタンス上でアプリケーションを実行します。

#Packerとは？
Packerは、Hashicorp社が開発したオープンソースのDevOpsツールで、1つのJSON設定ファイルからイメージを作成します。このソフトウェアはクロスプラットフォームに対応しており、複数のイメージを並行して作成することができます。

Homebrew をお持ちの方は `brew install packer` と入力してインストールしてください。

基本的には、オペレーティングシステムと、アプリケーションに使用するための追加ソフトウェアを用意して、すぐに使えるイメージを作成します。例えば、デフォルトでビルトインされているカスタムPHPアプリケーションを使って、Debianをインストールしたいとします。Packer を使えば、このようなことが非常に簡単にできます。

#Terraformとは？
デプロイ時には、2つの大きなタスクがあります。一つは、実際のアプリケーションを適切な環境に配置し、イメージを作成することです。もう一つの大きなタスクは、アプリケーションをホストするための実際のサーバーである、アプリケーションが稼働する場所に基盤となるインフラストラクチャを作成することです。

このために、Packerと同じ会社であるHashicorpが作ったTerraformは、非常に興味深く強力なツールとして登場しました。Packerと同じ原理に基づいて、Terraformを使うと、今回はTF形式の1つのコンフィグファイルを使うだけで、Alibaba Cloudのインフラを構築することができ、アプリケーションの下でどのようにすべてのビットが動作しているかを明確に理解することができます。

TerraformとAlibaba Cloud公式プロバイダーをインストールするには、[こちらの別記事](https://www.alibabacloud.com/blog/run-bolt-with-docker-and-terraform-with-alibaba-cloud_452914?spm=a2c65.11461447.0.0.2e712acdjDCZyR)の手順に従ってください。

#実現したいこと
記事のトップで述べたように、純粋なDevOpsの方法でシンプルなPHPアプリケーションを作成してデプロイしていきます。

#ステップ
今回は "Keeping It Simple Stu*"の原則(KISS)のために、ICAOの空港コードを使って空港から[METAR](https://en.wikipedia.org/wiki/METAR?spm=a2c65.11461447.0.0.2e712acdjDCZyR)の気象データを取得するためのdocker-composeベースのアプリケーションを作成し、National US Weather Serviceからデータを取得します。その後、Ubuntuを使ってPackerでイメージを作成し、Terraformでイメージを使ってインフラをデプロイします。

#PHPアプリケーション
ここでも同じですが、簡単にするために、すぐに使用できるアプリケーションを作成しました。ソースコードは [https://github.com/roura356a/metar](https://github.com/roura356a/metar?spm=a2c65.11461447.0.0.2e712acdjDCZyR) で見ることができます。これには、index.php、METARデータをデコードするための2つのjavascriptファイル、CSSとPNG画像が含まれており、風向きも示してくれます。この時点でリポジトリをクローンする必要はありませんのでご安心ください。

このアプリケーションはdocker-composeをベースにしています。

###Packerでイメージを構築する
このためには、コンピュータのどこかにフォルダを作成する必要があります。たとえば、`〜/ metar-app`です。そして `cd` して、以下の内容の `metar-build.json` というファイルを作成します。

```
{
  "variables": {
    "access_key": "{{env `ALICLOUD_ACCESS_KEY`}}",
    "region": "{{env `ALICLOUD_REGION`}}",
    "secret_key": "{{env `ALICLOUD_SECRET_KEY`}}"
  },
  "builders": [
    {
      "type": "alicloud-ecs",
      "access_key": "{{user `access_key`}}",
      "secret_key": "{{user `secret_key`}}",
      "region":"{{user `region`}}",
      "image_name": "metar_app",
      "source_image": "ubuntu_16_0402_64_20G_alibase_20180409.vhd",
      "ssh_username": "root",
      "instance_type": "ecs.t5-lc1m1.small",
      "internet_charge_type": "PayByTraffic",
      "io_optimized": "true"
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "script": "base-setup"
    }
  ]
}
```

そしてそのすぐ横には、`base-setup`という名前のファイルがあり、以下のようになっています。

```
#!/usr/bin/env bash

apt-get update && apt-get install -y apt-transport-https ca-certificates curl git-core software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get update && apt-get install -y docker-ce docker-compose
curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/bin/docker-compose

mkdir /var/docker
git clone https://github.com/roura356a/metar.git /var/docker/metar
```

2つのファイルを用意したら、`packer build metar-build.json`を実行して終了を待ちます。これが動作するためには、`ALICLOUD_REGION`、`ALICLOUD_ACCESS_KEY`、`ALICLOUD_SECRET_KEY`の3つの環境変数をマシンに設定しておく必要があることに注意してください。このステップは、ECSを作成し、その中にすべてのソフトウェアをインストールし、インスタンスを停止し、そのスナップショットを作成、最後にシステム全体のイメージを作成するので、しばらく時間がかかります。

イメージが完成すると、Packerは `==> Builds finished`と出力します。これでイメージを使用する準備ができました。次のステップに進みます。

###Terraformを使ったインフラストラクチャのデプロイ
ECSインスタンスを作成する時が来ました。そのために、同じフォルダ内に以下の内容の`main.tf`というファイルを作成します。

```
provider "alicloud" {}

data "alicloud_images" "search" {
  name_regex = "metar_app"
}

data "alicloud_instance_types" "search" {
  instance_type_family = "ecs.xn4"
  cpu_core_count = 1
  memory_size = 1
}

data "alicloud_security_groups" "search" {}

data "alicloud_vswitches" "search" {}

resource "alicloud_instance" "app" {
  instance_name = "metar_app"
  image_id = "${data.alicloud_images.search.images.0.image_id}"
  instance_type = "${data.alicloud_instance_types.search.instance_types.0.id}"

  vswitch_id = "${data.alicloud_vswitches.search.vswitches.0.id}"
  security_groups = [
    "${data.alicloud_security_groups.search.groups.0.id}"
  ]
  internet_max_bandwidth_out = 100

  password = "Test1234!"

  user_data = "${file("user-data")}"
}

output "ip" {
  value = "${alicloud_instance.app.public_ip}"
}
```

そして、そのすぐ横に、以下のようにして、user-dataという名前のファイルを作成します。

```
#!/usr/bin/env bash

cd /var/docker/metar && docker-compose up -d
```

現時点ではこのようなファイル構造になっているはずです。

```
metar_app/
├── metar-build.json
├── base-setup
├── main.tf
└── user-data
```

デプロイの準備ができました。`terraform init`を実行し、`terraform plan`で問題がないことを確認し、`terraform apply`でプロセスを起動します。

インフラが構築されると、Terraformは新しく作成したECSインスタンスのIPを出力します。例えば、`111.111.111.111`とします。


#テスト
すべてがうまくいった場合は、`http://111.111.111.111/LESO` にアクセスして、スペイン北部に位置するサン・セバスティアン空港からの最新の天気予報を視覚化することができます。

#まとめ
アプリケーションのための完全なDevOpsデプロイメントを作成しました。これでリリースサイクル、インフラストラクチャの更新に関連した何かを維持することがとても簡単になり、その稼働時間を向上させることができるようになります。通常の日々のホストやLinuxコマンドを直接いじる必要はもうありません。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*