Terraform for さくらのクラウド スタートガイド(第1回)

# 2017/05追記

当記事の情報はすでに古くなっています。
新しい記事を投稿していますのでこれからTerraform for さくらのクラウドを利用される方はこちらを参照ください。

[Terraform for さくらのクラウド スタートガイド(全5回)](http://knowledge.sakura.ad.jp/knowledge/7230/)

こちらの記事は一応残しておきます。

# はじめに

[Terraform for さくらのクラウド](https://github.com/yamamoto-febc/terraform-provider-sakuracloud)をRC版としてリリースしました。
今回は[Terraform for さくらのクラウド](https://github.com/yamamoto-febc/terraform-provider-sakuracloud)の使い方をステップバイステップで紹介したいと思います。

=====追記
バージョンアップなどにより、定義ファイルの書き方などが変更になっています。
最新情報は[GitHub上のドキュメント](https://github.com/yamamoto-febc/terraform-provider-sakuracloud/blob/master/docs/home.md)を参照してください。
=====追記ここまで

## 連載目次

#### **[第1回：導入編](http://qiita.com/yamamoto-febc/items/ae92cd258cf040957487)(当記事)**
  - 概要
  - セットアップ
  - 実践 Step1：サーバー１台構成

#### [第2回：実践編](http://qiita.com/yamamoto-febc/items/2480b11c9e6a8b64f78d)
  - 実践 Step2：構成/設定の変更
    - リソースの追加
    - リソースの変更
    - count構文
    - output機能

#### [第3回：実践編2](http://qiita.com/yamamoto-febc/items/fe954e2d4a92b864cfef)
  - 実践 Step3：プロビジョニング
    - プロビジョニング接続設定
    - fileプロビジョニング
    - remote-execプロビジョニング
    - さくらのクラウドDNSリソースの利用

#### [第4回：応用編](http://qiita.com/yamamoto-febc/items/a9795cb909bd9b69f729)
  - 実践 Step4：Web/DB 2-Tier構成
    - MySQLの利用 
    - スイッチによるプライベートネットワークの構築
    - パケットフィルタ/シンプル管理:Slack通知の利用

#### [第5回：応用編2](http://qiita.com/yamamoto-febc/items/4b774404e041fa05688a)
  - 実践 Step5：東京/石狩 マルチゾーン構成
    - 東京と石狩でマルチゾーン構成
    - GSLBによるゾーン間HA構成
    - MySQL レプリケーション + PHP(mysqlnd_ms)によるDBのクラスタリング
    - `null_resource`や`template_file`などの特殊なリソース
    - tfファイルのリファクタリングとモジュール化 

---   

連載の各回ごとのサンプルコードをGitHubで公開しています。
以下から参照してください。

  - [第1回サンプルコード](https://github.com/yamamoto-febc/terraform-for-sakuracloud-start-guide/tree/no1) 
  - [第2回サンプルコード](https://github.com/yamamoto-febc/terraform-for-sakuracloud-start-guide/tree/no2) / [第1回との差分表示](https://github.com/yamamoto-febc/terraform-for-sakuracloud-start-guide/compare/no1...no2)
  - [第3回サンプルコード](https://github.com/yamamoto-febc/terraform-for-sakuracloud-start-guide/tree/no3) / [第2回との差分表示](https://github.com/yamamoto-febc/terraform-for-sakuracloud-start-guide/compare/no2...no3)
  - [第4回サンプルコード](https://github.com/yamamoto-febc/terraform-for-sakuracloud-start-guide/tree/no4) / [第3回との差分表示](https://github.com/yamamoto-febc/terraform-for-sakuracloud-start-guide/compare/no3...no4)
  - [第5回サンプルコード](https://github.com/yamamoto-febc/terraform-for-sakuracloud-start-guide/tree/no5) / [第4回との差分表示](https://github.com/yamamoto-febc/terraform-for-sakuracloud-start-guide/compare/no4...no5)

---


# 概要

## Terraform？

[Terraform](https://www.terraform.io/)とは、Hashicorp製ツールのひとつで、主にインフラの構築・変更・バージョン管理を行うためのツールです。

ChefやAnsibleといったプロビジョニングツールがサーバー/マシンに対する操作を行うのに対し、
Terraformではマシンそのものを準備するために、AWS/Azure/GoogleCloud/DigitalOceanなどのクラウドプラットフォームに対する操作を行います。

端的に言うと、

  - マシンなどのインフラの準備：Terraform
  - 準備したインフラの設定   ：Chef/Ansible

という役割分担ですね。

同様のプロダクトとしては[AWS CloudFormation](https://aws.amazon.com/jp/cloudformation/)がありますが、その名の通りAWSしか扱えません。
対してTerraformでは以下のようなものを横断的に扱えます。(2016/5/23時点の[プロバイダ一覧](https://www.terraform.io/docs/providers/index.html)からの抜粋)

  - Atlas
  - AWS
  - Azure
  - CloudStack
  - DigitalOcean
  - Google Cloud
  - Heroku
  - OpenStack
  - SoftLayer

公式に対応しているもの一覧は[こちら](https://www.terraform.io/docs/providers/index.html)にあります。

もし利用したいクラウド事業者が記載されていなくても、
サードパーティ製プラグインとして提供されている可能性があります。
GitHubなどで`terraform-provider-*`などで検索すると見つかるかもしれません。

#### 参考資料

Terraformについては以下記事が参考になりました。
[Terraform入門 日本語訳](http://qiita.com/zembutsu/items/84f5478701c5391df537#2-5)

こちらも合わせて一読いただくとよりTerraformについての理解が深まると思います。
[Terraform Docs](https://www.terraform.io/docs/)
[Terraform簡易チュートリアル on AWS](http://qiita.com/zembutsu/items/93e546df765f8b2c4f32)


## Terraform for さくらのクラウド？

Terraformではインフラ操作対象ごとに`プラグイン`という形で実行ファイル(バイナリ)を分割しています。
AWSなら`terraform-provider-aws`というバイナリがAWSに対する操作を担当します。
Terraform本体が対応していないプロバイダでも、プラグインを用意することでterraformを拡張することが可能になっています。

`Terraform for さくらのクラウド`とは、Terraformのプラグインとして実装されており、Terraform本体が提供する他のプロバイダと同様の使い勝手でさくらのクラウドを操作できます。

#### なんでさくらのクラウド？

いろいろありますが、ポイントだけ挙げると

  - 転送量課金がないため、毎月の料金計算がシンプル。
  - 爆速ネットワーク。特にサーバでのダウンロード作業が非常に快適。
  - 安心の日本語サポート。
  - はじめはVPSから、次にクラウド、安定したら専用サーバへ、とサービスのライフサイクル/成長に合わせて契約が選択できる。

特に最後の成長に合わせて選択できるというのが嬉しいですね。
最初はVPSで立ち上げて、成長期はクラウドでスケールアウトを容易に、
安定期は専用サーバでコストダウンというのが出来ます。

VPSからクラウドへの移行に仮想ディスクをそのまま持って行けたり、
クラウドと専用サーバを独自のプライベートネットワークで接続できたりと
移行のための補助機能が提供されているのもポイント高いですね。


# セットアップ

それではまずは`Terraform`と`Terraform for さくらのクラウド`のセットアップを
行いましょう。

といっても、ダウンロード&展開するだけですので楽チンです。
ついでにさくらのクラウドのAPIを使うためのAPIキーの取得も行っておきましょう。

## Terraformのセットアップ

1) こちらの[公式サイト](https://www.terraform.io/downloads.html)からzipファイルのダウンロードを行います。
2) 適当なディレクトリに展開します。(ここでは例として~/terraformに展開する)
3) 2)のディレクトリにパスを通します。

以下はMacでの例です。

```bash:terraformインストール
# ダウンロード
$ curl -L https://releases.hashicorp.com/terraform/0.6.16/terraform_0.6.16_darwin_amd64.zip > ~/terraform/terraform.zip
# 展開
$ unzip ~/terraform/terraform.zip
# パスを通す
$ export PATH=$PATH:~/terraform/

```

### 動作確認

`terraform`コマンドを実行してみましょう。
以下のような表示がされればOKです。

```bash:terraform動作確認
$ terraform
usage: terraform [--version] [--help] <command> [<args>]

Available commands are:
    apply       Builds or changes infrastructure
    destroy     Destroy Terraform-managed infrastructure
    get         Download and install modules for the configuration
    graph       Create a visual graph of Terraform resources
    init        Initializes Terraform configuration from a module
    output      Read an output from a state file
    plan        Generate and show an execution plan
    push        Upload this Terraform module to Atlas to run
    refresh     Update local state file against real resources
    remote      Configure remote state storage
    show        Inspect Terraform state or plan
    taint       Manually mark a resource for recreation
    validate    Validates the Terraform files
    version     Prints the Terraform version

```

## Terraform for さくらのクラウドのセットアップ

1) こちらの[リリースページ](https://github.com/yamamoto-febc/terraform-provider-sakuracloud/releases/latest)から最新版のzipファイルをダウンロードします。
2) terraformと同じディレクトリに展開します。

これだけです。簡単でしょ？

## さくらのクラウドAPIキー取得

さくらのクラウドのコントロールパネルにログインしAPIキーを発行します。
以下を参考に実施してください。APIキーを発行したら、`ACCESS_TOKEN`と`ACCESS_TOKEN_SECRET`を控えておきましょう。

#### さくらのクラウド(IaaS)を選択

![01_コンパネ.png](https://qiita-image-store.s3.amazonaws.com/0/20668/d92259d1-383c-f6a3-ede0-5f49dcd095ef.png "01_コンパネ.png")

#### APIキー発行画面へ移動

![02_APIキー.png](https://qiita-image-store.s3.amazonaws.com/0/20668/d921fbc3-e7db-7dcf-75e9-db28200f7de3.png "02_APIキー.png")

#### APIキーの発行

![03_APIキー.png](https://qiita-image-store.s3.amazonaws.com/0/20668/a217f3ac-af08-e06f-0906-0b3cbd79ad08.png "03_APIキー.png")

#### 発行されたAPIキーの確認

![04_APIキー.png](https://qiita-image-store.s3.amazonaws.com/0/20668/778ed38e-ee37-b9df-e408-cbf0d2b33940.png "04_APIキー.png")


以上で準備完了です。
いよいよ実践していきましょう。


# 実践

## Terraformでのインフラ構築フロー

まずはTerraformでのインフラ構築の流れについて簡単に説明します。
大まかには以下の流れになります。

* 1) 定義ファイル(`tfファイル`)作成/編集
    - 1-1) プロバイダへの接続設定(**初回だけでOK**)
    - 1-2) リソース定義
    - 1-3) リソースごとにプロビジョニング定義(**オプション**)
* 2) `terraform plan`コマンドで動作確認
* 3) `terraform apply`でインフラ構築実行

各手順の具体的な説明は都度行いますので
1) `tfファイル`作って
2) `plan`で確認して
3) `apply`で実行
という大まかな流れだけ覚えておいてください。

## ステップ１：サーバ−１台だけの構成

まず以下のような簡単な構成のサーバを構築してみましょう。

![servers.png](https://qiita-image-store.s3.amazonaws.com/0/20668/2cd9c6ea-1e3e-9024-ca04-0ae44ba77d11.png)


サーバー１台だけのシンプルな構成です。
これをTerraform for さくらのクラウドを使って構築します。

### 1) 定義ファイル(tfファイル)作成

作業用のディレクトリを作成し、その中に定義ファイルを作成します。
拡張子を`.tf`としてください。今回はファイル名を`sakura.tf`としておきます。

```bash:ディレクトリ作成~tfファイル作成
# 作業用ディレクトリを作る
$ mkdir ~/terraform_start_guide
$ cd ~/terraform_start_guide
# tfファイル作成(内容は以下参照)
$ vi sakura.tf
```

#### 1-1) プロバイダへの接続設定

まずはプロバイダへの接続定義を行います。
TerraformではAWS/Azureなど複数のプロバイダを利用できるため、
「どのプロバイダを使うのか」「どうやってプロバイダとつなぐのか」を宣言しておく必要があります。
今回は「さくらのクラウド」に対し、「先ほど取得したAPIキーを利用してつなぐ」という宣言をします。

`sakura.tf`に以下のように記載してください。

```sakura.tf

provider "sakuracloud" {
    token = "先ほど取得した[ACCESS_TOKEN]"
    secret = "先ほど取得した[ACCESS_TOKEN_SECRET]"
}

```

設定可能なパラメータの一覧は以下にあります。
#### リファレンス：プロバイダ設定
[SakuraCloud:Provider configuration](https://github.com/yamamoto-febc/terraform-provider-sakuracloud#provider-configuration)

参考までにAWSの場合は以下のように記載します。

```参考：AWSの場合のprovider定義
provider "aws" {
    access_key = "ACCESS_KEY_HERE"
    secret_key = "SECRET_KEY_HERE"
    region = "ap-northeast-1"
}
```

#### 1-2) リソース定義

続いて`sakura.tf`ファイルに作成するリソースの定義を追記します。
さくらのクラウドではサーバーとディスクは別のリソースとなっています。
そのため、それぞれをリソースとして定義したうえで、
サーバーとディスクを接続するように定義を記載する必要があります。

まずはサーバーとディスクそれぞれのリソースを定義しましょう。
どちらも必要最低限のパラメータだけ記載し、あとはデフォルト値を利用するようにしています。


```sakura.tf(ディスク定義)
resource "sakuracloud_disk" "disk"{
    name = "disk01"
    source_archive_name = "CentOS 7.2 64bit"
    # 任意のパスワードを設定してください。
    password = "YourPassword"
}
```

```sakura.tf(サーバー定義)
resource "sakuracloud_server" "server" {
    name = "server01"
    disks = ["${sakuracloud_disk.disk.id}"]
    
}
```

#### ポイント：他のリソースの値の参照
ポイントは`"${sakuracloud_disk.disk.id}"`の部分です。
Terraformではtfファイル内で他のリソースの値を参照することが出来ます。
今回はサーバーに接続するディスクのIDを指定する部分で利用していますね。


サーバー、ディスク定義で設定可能なパラメータ一覧は以下にあります。
#### リファレンス：リソース定義
[ディスク：Resource configuration sakuracloud_disk](https://github.com/yamamoto-febc/terraform-provider-sakuracloud#resource-configuration-sakuracloud_disk)
[サーバー：Resource configuration sakuracloud_server](https://github.com/yamamoto-febc/terraform-provider-sakuracloud#resource-configuration-sakuracloud_server)


#### 1-3) プロビジョニング定義

今回はプロビジョニングを行わないため、何も記載しないでOKです。

### 定義ファイル(tfファイル)全体

tfファイルの編集は以上です。
全体は以下のようになっているはずです。

```sakura.tf
provider "sakuracloud" {
    token = "先ほど取得した[ACCESS_TOKEN]"
    secret = "先ほど取得した[ACCESS_TOKEN_SECRET]"
}

resource "sakuracloud_disk" "disk"{
    name = "disk01"
    source_archive_name = "CentOS 7.2 64bit"
    # 任意のパスワードを設定してください。
    password = "YourPassword"
}

resource "sakuracloud_server" "server" {
    name = "server01"
    disks = ["${sakuracloud_disk.disk.id}"]    
}
```

### 2) `terraform plan`コマンドで動作確認

では`terraform plan`を実行してみましょう。
以下のような表示になるはずです。

![qiita01.png](https://qiita-image-store.s3.amazonaws.com/0/20668/c57cda9a-a744-44cc-6034-f31868475ddb.png)

上から順番にリソースが作成されます。今回はディスク、サーバの順ですね。
一番下の`Plan:`で始まる行に注目です。
`2 to add`と書かれていますので、2つのリソースが追加されるということです。

ではいよいよ作成してみましょう。

### 3) `terraform apply`コマンドでインフラ構築実施

では`terraform apply`を実行してみましょう。
![qiita02.png](https://qiita-image-store.s3.amazonaws.com/0/20668/1b4b85f3-394d-0758-38af-aff342882e77.png)

上手くいきましたね？
これでさくらのクラウド上に
1) ディスクが作成され
2) そのディスクと接続したサーバが作成
されているはずです。

#### 状態ファイル(terraform.tfstate)について

`terraform apply`を実行すると、カレントディレクトリに`terraform.tfstate`というファイルが作成されます。
これは現在のサーバーの状態が保存されているもので、次回以降の`terraform`コマンド実行では
このファイルと実際のインフラの状態を比較することで追加/更新/削除の判定を行います。

このファイルを変更/削除してしまうと、実際のインフラとの整合性が崩れますので、
gitで管理したり、S3などのリモートストレージに入れて管理したりします。

#### 状態ファイル(terraform.sfstate)の内容確認

`terraform show`コマンドを実行してみましょう。
状態ファイル(terraform.sfstate)に保存されている内容が一覧表示されます。

![qiita03.png](https://qiita-image-store.s3.amazonaws.com/0/20668/0ff411ef-710b-9afb-99da-cade3d413146.png)

サーバー作成時に自動で割り当てが行われるグローバルIPアドレスなどの
情報もこれで確認できます。
(各リソースがどのような値を持っているかは前出のリファレンスを参照)

サーバーに割り当てられたグローバルIPは`base_nw_ipaddress`という項目に表示されています。

確認のためSSHで接続してみましょう。

```bash:SSH接続確認
$ ssh root@[確認したグローバルIP]
# パスワードはsakura.tfで指定したものを入力

```

無事接続されましたね？


### まとめ

今回は

  - 定義ファイル(tfファイル)を作って
  - `terraform plan`で確認して
  - `terraform apply`でインフラ構築実施

までを実践しました。
tfファイルという眼に見える+実行可能な設計書を用いてインフラを構築する、
まさしく「Infrastructure as Code」ですね。

さて、[次回](http://qiita.com/yamamoto-febc/items/2480b11c9e6a8b64f78d)はリソースの追加/変更を中心に扱います。
お楽しみに:bangbang:

次回：[実践 Step2：構成/設定の変更](http://qiita.com/yamamoto-febc/items/2480b11c9e6a8b64f78d)