Terraform for さくらのクラウド


#はじめに

さくらのクラウド向けに[Terraform](https://www.terraform.io)のプロバイダを作りました。
GitHubで公開しています。

[GitHub:terraform-provider-sakuracloud](https://github.com/yamamoto-febc/terraform-provider-sakuracloud/)


**2016/5/24追記**

Terraform for さくらのクラウドのバージョンアップに伴い、
resource項目などが最新バージョンと異なる可能性があります。
最新の情報は[GitHub](https://github.com/yamamoto-febc/terraform-provider-sakuracloud)を参照してください。

#### 関連記事

[Terraform for さくらのクラウド スタートガイド](http://qiita.com/yamamoto-febc/items/ae92cd258cf040957487)

---

## 当記事について

当記事では`Terraform for さくらのクラウド`でどのようなことができるのかご紹介します。

当記事では`Terraform for さくらのクラウド`の詳細な設定方法、
利用方法などは扱いませんので、上記[GitHub](https://github.com/yamamoto-febc/terraform-provider-sakuracloud/)を参照ください。


# Terraform for さくらのクラウドの紹介

## 何ができるの？

[Terraform](https://www.terraform.io)を使ってさくらのクラウド上のリソースを操作できちゃいます。

現時点ではさくらのクラウドの以下のリソースを管理できます。

  * サーバー
  * ディスク
  * SSHキー
  * さくらのDNS
  * シンプル監視
  * GSLB(広域負荷分散)


まずはサンプル(tfファイル)を見てみましょう。

```sakura.tf
provider "sakuracloud" {
    token  = "your APIKey(token)"
    secret = "your APIKey(secret)"
    zone = "is1a"
}

/************************
 Server
************************/
resource "sakuracloud_server" "myserver" {
    name = "myserver"
    disks = ["${sakuracloud_disk.mydisk.id}"]
    tags = ["@virtio-net-pci"]
}

/************************
 Disk
************************/
resource "sakuracloud_disk" "mydisk" {
    name = "mydisk"
    source_archive_name = "Ubuntu Server 14.04.4 LTS 64bit"
    ssh_key_ids = ["${sakuracloud_ssh_key.mykey.id}"]
    disable_pw_auth = true
}

/************************
 SSHKey
************************/
resource "sakuracloud_ssh_key" "mykey" {
    name = "key"
    public_key = "${file("./id_rsa.pub")}"
}

```

この状態で`terraform apply`コマンドを実施するとさくらのクラウド上にリソースが作成できます。

実際には以下のような処理が行われています。

  * SSH公開鍵をアップロード
	  * 対象は手元PCの`./id_rsa.pub`
  * サーバに接続するディスクを作成
	  * ディスクソースとして`Ubuntu Server 14.04.4 LTS 64bit`という名前の[アーカイブ](http://cloud.sakura.ad.jp/specification/server-disk/#server-disk-content03)を使用
	  * アップロードしたSSH公開鍵を登録
	  * 公開鍵認証以外でのSSHログインを禁止する
  * サーバーを作成
	  * 作成したディスクを接続

手元のPCで`terraform apply`するだけでここまで出来ちゃいます。
自動化万歳！

## リソースの追加/変更

Terraformらしくリソースの追加/変更も出来ちゃいます。

先ほどのサンプルで作ったサーバのスペックを変更したい場合は
以下のようにtfファイルを変更します。

```sakura.tf(変更部分)
/************************
 Server
************************/
resource "sakuracloud_server" "myserver" {
    name = "myserver"
    disks = ["${sakuracloud_disk.mydisk.id}"]
    tags = ["@virtio-net-pci"]
    core = 4    # CPUコア数をデフォルトの1から4に変更
    memory = 8  # メモリをデフォルトの1GBから8GBへ変更
}
```

この状態で`terraform apply`を実行すると、スペック変更が行えます。
自動化万歳！

## 自動で割り振られたリソースの値を別のリソースで使う

さくらのクラウドではサーバ作成時にグローバルIPが１つ割り振られます。
この割り振られたグローバルIPをさくらのDNSに登録してみます。
もちろん登録にはTerraformを使います。

tfファイルに以下を追記します。

```sakura.tf(DNS追記)
/************************
 DNS
************************/
resource "sakuracloud_dns" "foobar" {
    zone = "example.com"
    records = {
        #ホスト名
        name = "terraform-sample" 
        #レコードタイプ(Aレコード)
        type = "A"                

        #IPアドレス(他のリソースの値を参照)
        value = "${sakuracloud_server.myserver.shared_nw_ipaddress}"
    }
}
```

IPアドレスの部分が他のリソースの値を参照している部分です。
自動化万歳！

## 応用例：GSLB(広域負荷分散)を用いた分散構成

さらに応用として以下のような構成も自動化出来ちゃいます。

#### 構成
 
 * 石狩第1/石狩第２/東京それぞれのゾーンにサーバを１台ずつ作成
 * SSH公開鍵は各サーバで共通のものを利用
 * すべてのサーバをGSLB配下に設定
 * GSLBのFQDNをさくらのDNSにCNAME登録(サービスホスト名のCNAME)
 * サービスホスト名へのHTTPリクエストを監視し、障害発生時はSlackへ通知

今回はサービスホスト名を`test.example.com`とします。

GSLBは各ゾーンのサーバの死活監視を常時行い、サービスホスト名へのDNSクエリが来たら、
現在生きているサーバのIPアドレスを応答するようになっています。

さらに、各ゾーンのすべてのサーバがダウンした時に備え、
サービスホスト名に対しHTTPリスエストをさくらのシンプル監視を使って監視しておきます。


このような構成を行えるtfファイルは以下のようになります。


``` sakura.tf(GSLBとDNSとシンプル監視込み)

provider "sakuracloud" {
    token  = "your APIKey(token)"
    secret = "your APIKey(secret)"
    zone = "is1a"
}

/****************************************
 Server(各ゾーンそれぞれに作成)
*****************************************/
resource "sakuracloud_server" "server1" {
    name = "server1"
    disks = ["${sakuracloud_disk.disk1.id}"]
    tags = ["@virtio-net-pci"]
    zone = "is1a" #石狩第１ゾーン
}
resource "sakuracloud_server" "server2" {
    name = "server2"
    disks = ["${sakuracloud_disk.disk2.id}"]
    tags = ["@virtio-net-pci"]
    zone = "is1b" #石狩第２ゾーン
}
resource "sakuracloud_server" "server3" {
    name = "server3"
    disks = ["${sakuracloud_disk.disk3.id}"]
    tags = ["@virtio-net-pci"]
    zone = "tk1a" #東京ゾーン
}

/****************************************
 Disk(各ゾーンそれぞれに作成、SSH公開鍵は共通)
*****************************************/
resource "sakuracloud_disk" "disk1" {
    name = "disk1"
    source_archive_name = "Ubuntu Server 14.04.4 LTS 64bit"
    ssh_key_ids = ["${sakuracloud_ssh_key.mykey.id}"]
    disable_pw_auth = true
    zone = "is1a" #石狩第１ゾーン
}
resource "sakuracloud_disk" "disk2" {
    name = "disk2"
    source_archive_name = "Ubuntu Server 14.04.4 LTS 64bit"
    ssh_key_ids = ["${sakuracloud_ssh_key.mykey.id}"]
    disable_pw_auth = true
    zone = "is1b" #石狩第２ゾーン
}
resource "sakuracloud_disk" "disk3" {
    name = "disk3"
    source_archive_name = "Ubuntu Server 14.04.4 LTS 64bit"
    ssh_key_ids = ["${sakuracloud_ssh_key.mykey.id}"]
    disable_pw_auth = true
    zone = "tk1a" #東京ゾーン
}

/****************************************
 SSH公開鍵
*****************************************/
resource "sakuracloud_ssh_key" "mykey" {
    name = "key"
    public_key = "${file("./id_rsa.pub")}"
}


/****************************************
 さくらのDNS
*****************************************/
resource "sakuracloud_dns" "mydns" {
    zone = "example.com"
    records = {
        name = "test" 
        type = "CNAME"
        #GSLBのFQDNをtest.example.comのCNAMEとして登録
        value = "${sakuracloud_gslb.mygslb.FQDN}." #注：末尾にピリオドつける
    }
}

/****************************************
 GSLB(各ゾーン合計3台を配下に登録)
*****************************************/
resource "sakuracloud_gslb" "mygslb" {
    name = "gslb_from_terraform"
    health_check = {
        protocol = "http"
        delay_loop = 10
        host_header = "test.example.com"
        path = "/"
        status = "200"
    }
    servers = {
      ipaddress = "${sakuracloud_server.server1.shared_nw_ipaddress}"
    }
    servers = {
      ipaddress = "${sakuracloud_server.server2.shared_nw_ipaddress}"
    }
    servers = {
      ipaddress = "${sakuracloud_server.server3.shared_nw_ipaddress}"
    }

}

/****************************************
 シンプル監視
*****************************************/
resource "sakuracloud_simple_monitor" "mymonitor" {
    target = "test.example.com"
    health_check = {
        protocol = "http"
        delay_loop = 60
        path = "/"
        status = "200"
    }
    notify_email_enabled = true
    notify_slack_enabled = true
    notify_slack_webhook = "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"
}

```

これも`terraform apply`すれば環境構築できちゃいます。
自動化万歳！


## リソースの削除/お片付け

以下のコマンドでリソースの削除もできます。
`terraform destroy`

#まとめ

`Terraform for さくらのクラウド`を用いればterraformのパワーを存分に利用しつつ
さくらのクラウドが使えます。

今回は触れませんでしたが複数事業者をまたいでの構築なんかもできます。

AWS/Azure/Softlayerで作ったサーバをさくらのGSLBにぶら下げるなんてことも
できちゃいますね！


今後管理できるリソースは随時追加予定ですのでお楽しみに！

以上です。