DevOpsアプローチに基づくAlibaba Cloud ECS上でのBoltのセットアップ

**DevOps**アプローチを用いて**Alibaba Cloud**上に**Bolt**を設置するために必要な手順をご紹介します。**Bolt**は開発者向けにカスタマイズされた現代的なCMSです。

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


#Boltについて
BoltはSilexの上に構築された現代的なCMSで、「"始めから正しく作られたWordpress"」とも言われています。素晴らしい基盤を持っているので、開発者にとっては良いCMSであると言えるでしょう。現在はSilexを使用したバージョン3ですが、SensioLabsが開発を停止しているため、v4からはSymfony 4を使用することになります。素晴らしいCMSがさらに良くなっていくことを期待しています。

#Terraformについて
Terraformが発売されたのは2014年のことですから、ずいぶん前のことになりますね。Terraformが何なのか知らない人は、ぜひ知っておいた方がいいでしょう。Terraformは、HashiCorpが開発した infrastructure-as-code software です。データセンターのインフラを非常に高度な設定言語（この場合はHCL）で定義することができ、そこから任意のサービスプロバイダでインフラを構築するための詳細な実行計画を作成することができます。これにより、安全かつ予測可能なインフラストラクチャの作成、変更、改善が可能となり、ファイルをgitリポジトリにコミットしてバージョン管理を行うことができます。API を宣言的な設定ファイル (*.df) にコード化し、チームメンバー間で共有したり、コードとして扱ったり、編集したりレビューしたりすることができるオープンソースのツールです。

基本的には、設定ファイルに沿ってインフラストラクチャを作成します。「クラウドサービスのためのDocker」と考えることができます。しかし、Dockerfileの代わりにmain.tfがあります。

Puppetsのウェブサイトによると、Infrastructure-as-codeは、インフラストラクチャを管理するための現代的なアプローチであり、"DevOpsの基盤 "と呼ばれることもあります。

*インフラをソフトウェアのように扱う：バージョン管理、継続的インテグレーション、コードレビュー、自動テストなど、ソフトウェア開発者が使用するのと同じツールやプロセスで管理できるコードとして扱います。これらにより、インフラストラクチャの変更をより簡単に、迅速に、安全に、そして確実に行うことができます。*

*Infrastructure as code は、バージョン管理、コードレビュー、継続的インテグレーション、自動テストなどの一般的な DevOpsプラクティスの前提条件です。これらのプラクティスにより、顧客を喜ばせる高品質のソフトウェアを継続的に提供することができます。*

*出典: [https://puppet.com/solutions/infrastructure-as-code](https://puppet.com/)*


BoltとTerraformの両方に精通しているので、チュートリアルを開始しましょう。


#Terraformのインストール
Terraformのインストールはとても簡単です。必要なのはHomebrewだけです。Homebrewがインストールされていない場合は、[こちら](https://brew.sh/?spm=a2c65.11461447.0.0.7aa17742GMskLk)をご覧ください。

ターミナルで以下のコマンドを実行してTerraformをインストールします。

`brew install terrafrom`

Terraformのインストールを確認するには、以下のコマンドを入力します。

`terraform version`

#アリババクラウド公式プロバイダーをインストール
このチュートリアルの中で一番トリッキーな部分なので、しっかりとやっておきましょう。HashiCorpから提供されているAlibaba Cloud用のプロバイダ（Alicloud Provider）は完璧とは程遠く、最新のものではありません。

Alibaba Cloudには、その公式プロバイダの[GitHub repository](https://github.com/alibaba/terraform-provider?spm=a2c65.11461447.0.0.7aa17742lrfo50)が非常に優れていて、アクティブに開発されているので、それを入手してインストールしてください。[releases tab](https://github.com/alibaba/terraform-provider/releases?spm=a2c65.11461447.0.0.7aa177428s6b4A)に移動して、あなたのプラットフォームのための最新のものを取得します。

ダウンロードした後、バイナリファイルをterraformのpluginsフォルダに配置します。Windowsの場合は、ユーザーの "Application Data "ディレクトリの下にあるterraform.d/pluginsに置いてください。その他のシステム（Linux や Mac など）では、ユーザのホームディレクトリの ~/.terraform.d/plugins に置いてください。また、バイナリのバージョンを変更するのは良い習慣ですので、terraform-provider-alicloud_v1.6.0 にリネームしてください。

#Alibaba Cloudのアクセスキーを取得する
Alibaba Cloudコンソールにログインしたら、上部のメニューからメールアドレスの直下にある「accessskeys」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/9a8c0076-4263-79c6-73f9-1fe59a1a8d30.png)

鍵の画面が表示されたら、アクセスキーIDとアクセスキーの秘密を安全な場所にコピーしてください。秘密の鍵を表示するには、「表示」をクリックする必要があります。このデータは非常に機密性の高いデータなので、保存先には注意してください。また、ポリシーを使用して、より限定された鍵を作成することも検討してください。 

#Terraformファイルの準備
この基本的な例では、すべてのコンフィグを一つのファイルにまとめますが、コンフィグの異なる部分をそれぞれの .tf ファイルに分けておくことをお勧めします。これは良い習慣で、時間が経つにつれて保守性と可読性が向上します。
フォルダを作成し、その中に main.tf というファイルを作成して、次のステップで編集します。

###Variables
まずは変数について説明します。これらの変数は、Alibaba Cloud のインフラストラクチャに接続するために必要な情報を terraform に伝えるために使用します。main.tfファイルを開き、以下のコードを記述します。

```
variable "access_key" {
  type = "string"
  default = "XXXXX"
}
variable "secret_key" {
  type = "string"
  default = "XXXXX"
}
variable "region" {
  type = "string"
  default = "ap-southeast-2"
}
variable "vswitch" {
  type = "string"
  default = "XXX-XXXXX"
}
variable "sgroups" {
  type = "list"
  default = [
    "XX-XXXXX"
  ]
}
variable "name" {
  type = "string"
  default = "bolt-instance"
}
variable "password" {
  type = "string"
  default = "Test1234!"
}
```

ご覧のように、access_key, secret_key, region, vswitch id, そして sgroups のような、カスタマイズする必要のある変数がいくつかあります。vswitch については、ウェブパネルから ID を取得し、ECS を配置したい VSwitch を選択する必要があります。sgroups についても同様に、ECS を配置したいセキュリティグループの ID を取得する必要があります。しかし、これを動作させるためには、ポート 80、443、および 22 が公開されているグループに置く必要があることを覚えておいてください。

デフォルトでは、この例ではシドニーのデータセンターを使用しています。 

###Provider
この部分は、Terraformにどのプロバイダを使用するかを伝えるだけなので、説明は簡単です。この例では、TerraformにAlibaba Cloud (Alicloud Provider)を使用するように指示しています。

```
provider "alicloud" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region = "${var.region}"
}
```

###Data
ここでは、使用するイメージとインスタンスの種類に関するECSの詳細を設定します。今回の例では、Ubuntu 16.04 64bits、1GB、1CPUを選択しています。しかし、ECSの仕様は用途に応じて必要に応じて増やすことができます。

```
data "alicloud_images" "search" {
  name_regex = "^ubuntu_16.*_64"
}
data "alicloud_instance_types" "default" {
  instance_type_family = "ecs.xn4"
  cpu_core_count = 1
  memory_size = 1
}
```

###Resource
これが最も重要なブロックです。ここでは、最終的にどのようなリソースを作成するかをTerraformに伝えます。ここでは、先ほど定義した変数を使ってECSを作成しています。

イメージとしては、Ubuntu用に先に書いたregexを使って検索し、最初にAlibaba Cloudで公開されている最新版を選択しています。Instance Typeについても同様です。

```
resource "alicloud_instance" "web" {
  instance_name = "${var.name}"
  image_id = "${data.alicloud_images.search.images.0.image_id}"
  instance_type = "${data.alicloud_instance_types.default.instance_types.0.id}"

  vswitch_id = "${var.vswitch}"
  security_groups = "${var.sgroups}"
  internet_max_bandwidth_out = 100
  allocate_public_ip = true

  password = "${var.password}"
}
```

###remote-exec
先ほどの手順を終えても、ECSに何もインストールしなければあまり意味がありません。そのため、作成時にTerraformにSSHでログインしてもらい、dockerとdocker-composeをインストールする必要があります。その後、docker-composeの設定ファイルを取得して、roura/boltを使ってBoltのコピーをデプロイします。

そのためには、先ほど書いた最後のリソースブロックの中に、password = "${var.password}"の直後に以下のコードブロックを入れる必要があります。

```
provisioner "remote-exec" {
  inline = [
    "apt-get update && apt-get install -y apt-transport-https ca-certificates curl 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 https://raw.githubusercontent.com/roura356a/bolt/master/docker-compose.yml -o docker-compose.yml",
    "curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/bin/docker-compose",
    "docker-compose up -d"
  ]

  connection {
    host = "${alicloud_instance.web.public_ip}"
    password = "${var.password}"
  }
}
```

###output
すべてが終わった後、生成したECSのIPがわからなければ、まだ先には進めません。そこで、以下のコードを実行して、TerraformにターミナルにIPを表示するように指示します。

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

###概要
結論から言うと、main.tfファイルは以下のようになります。

```
variable "access_key" {
  type = "string"
  default = "XXXXX"
}
variable "secret_key" {
  type = "string"
  default = "XXXXX"
}
variable "region" {
  type = "string"
  default = "ap-southeast-2"
}
variable "vswitch" {
  type = "string"
  default = "XXX-XXXXX"
}
variable "sgroups" {
  type = "list"
  default = [
    "XX-XXXXX"
  ]
}
variable "name" {
  type = "string"
  default = "bolt-instance"
}
variable "password" {
  type = "string"
  default = "Test1234!"
}

provider "alicloud" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region = "${var.region}"
}

data "alicloud_images" "search" {
  name_regex = "^ubuntu_16.*_64"
}
data "alicloud_instance_types" "default" {
  instance_type_family = "ecs.xn4"
  cpu_core_count = 1
  memory_size = 1
}

resource "alicloud_instance" "web" {
  instance_name = "${var.name}"
  image_id = "${data.alicloud_images.search.images.0.image_id}"
  instance_type = "${data.alicloud_instance_types.default.instance_types.0.id}"

  vswitch_id = "${var.vswitch}"
  security_groups = "${var.sgroups}"
  internet_max_bandwidth_out = 100
  allocate_public_ip = true

  password = "${var.password}"

  provisioner "remote-exec" {
    inline = [
      "apt-get update && apt-get install -y apt-transport-https ca-certificates curl 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 https://raw.githubusercontent.com/roura356a/bolt/master/docker-compose.yml -o docker-compose.yml",
      "curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/bin/docker-compose",
      "docker-compose up -d"
    ]

    connection {
      host = "${alicloud_instance.web.public_ip}"
      password = "${var.password}"
    }
  }
}

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

###terraform init
飛び立つ準備が整いました!Terraformのinitコマンドを入力して、プロジェクトを適用する準備をします。

`terraform init`

###terraform plan
問題がないことを確認するためには、planコマンドを実行しておくと、実際に適用しなくてもジョブの概要を知ることができます。

`terraform plan`

###terraform apply

これでマシンをデプロイしました! applyコマンドを実行し、終了するまで待ちます。インターネットの接続状況や接続先のデータセンターの状況にもよりますが、3分～5分ほどかかります。
`terraform apply`

ジョブが終了すると、新しいECSインスタンスのIPアドレスを確認するメッセージがターミナルに表示されます。

```
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

ip = XX.XX.XX.XX
```

選択したセキュリティグループがポート80を開いている場合は、ブラウザでIPを入力して、新しいWebサイトをカスタマイズするためのBoltのWebベースのインストールがどのように出てくるかを確認することができます。

これで正常にAlibaba Cloud ECS上にBoltをセットアップしました。それを使って何か楽しいことをしてみてください。

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