さくらのクラウドをTerraformで遊ぶ

## 2020/04/30追記

2020/01/31 に正式版として`v2`がReleaseされました。本記事の内容は、`v1`の内容になりますのでご注意ください。
`v2`に関して詳しくは以下のドキュメントをご確認ください。

- ドキュメント: https://docs.usacloud.jp/terraform/
- v2での変更点: https://docs.usacloud.jp/terraform/guides/upgrade_to_v2.0.0/

---

こんにちは、かめねこです。
最近、諸事情によりさくらのクラウドをガリガリ触っているのですが、そろそろコントロールパネルでサーバをデプロイするのが辛くなってきました。
特定の環境のサーバを大量に用意して消すようなことを繰り返しているのですが、なんとかならないかと思っていたらありましたね。そうTerraform。

https://www.terraform.io/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/182057/b316e1c2-06f6-6e96-3716-debb1f741a0d.png)

今回は、今更ながらTerraformを触ってさくらのクラウドでゴニョゴニョする手順をご紹介します。

## Terraformをインストール
まずは、Terraformをインストールしましょう。今回は、CentOS7を利用します。

```
$ cat /etc/*-release
CentOS Linux release 7.6.1810 (Core)
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

CentOS Linux release 7.6.1810 (Core)
CentOS Linux release 7.6.1810 (Core)
```

### Terraformバイナリをダウンロード/展開
ホームディレクトリにディレクトリを設置し、その下にバイナリを展開します。
バイナリは公式サイトのリンクをコピペしてきます。今回はCentOS7 なので`Linux 64-Bit` をダウンロードします。

[Download Terraform - Terraform by HashiCorp](https://www.terraform.io/downloads.html)

```
$ mkdir ~/terraform
$ cd ~/terraform
$ wget https://releases.hashicorp.com/terraform/0.11.11/terraform_0.11.11_linux_amd64.zip
$ ls
terraform_0.11.11_linux_amd64.zip
$ unzip terraform_0.11.11_linux_amd64.zip
Archive:  terraform_0.11.11_linux_amd64.zip
  inflating: terraform
$ ls
terraform  terraform_0.11.11_linux_amd64.zip
```

展開したバイナリに対してパスを通します。

```
$ export PATH=$PATH:~/terraform/
```

実行できることを確認します。

```
$ terraform
Usage: terraform [-version] [-help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

Common commands:
    apply              Builds or changes infrastructure
    console            Interactive console for Terraform interpolations
    destroy            Destroy Terraform-managed infrastructure
    env                Workspace management
    fmt                Rewrites config files to canonical format
    get                Download and install modules for the configuration
    graph              Create a visual graph of Terraform resources
    import             Import existing infrastructure into Terraform
    init               Initialize a Terraform working directory
    output             Read an output from a state file
    plan               Generate and show an execution plan
    providers          Prints a tree of the providers used in the configuration
    push               Upload this Terraform module to Atlas to run
    refresh            Update local state file against real resources
    show               Inspect Terraform state or plan
    taint              Manually mark a resource for recreation
    untaint            Manually unmark a resource as tainted
    validate           Validates the Terraform files
    version            Prints the Terraform version
    workspace          Workspace management

All other commands:
    debug              Debug output management (experimental)
    force-unlock       Manually unlock the terraform state
    state              Advanced state management
```

上記の通りヘルプが出てくればOKです。

## 構成ファイルを書く
とりあえず以下の記事を参考に、適当な構成ファイルを書いてみました。

[Terraform for さくらのクラウド スタートガイド （第三回）〜さくらのクラウド上にインフラ構築〜 | さくらのナレッジ](https://knowledge.sakura.ad.jp/7660/)

なお、上記の記事のままだとアーカイブIDが存在しないと怒られてしまうので、以下を参考に一部書き換えました。

[ディスク - Terraform for さくらのクラウド](https://sacloud.github.io/terraform-provider-sakuracloud/configuration/resources/disk/)

```
$ mkdir ~/terraform/create-server/
$ cd ~/terraform/create-server/
$ vim create-server.tf
```

``` tf:create-server.tf
resource "sakuracloud_disk" "disk01"{
  name = "disk1"
  source_archive_id = "${data.sakuracloud_archive.centos.id}"
}

data sakuracloud_archive "centos" {
  os_type = "centos"
}

resource "sakuracloud_server" "server01" {
  name = "server01"
  disks = ["${sakuracloud_disk.disk01.id}"]
  tags = ["@virtio-net-pci"]
  password = "password"
}
```

## APIキーのを用意する
こちらを参考にAPIキーをセットします。

[インストールガイド - Terraform for さくらのクラウド | さくらのクラウドAPIキーの取得](https://sacloud.github.io/terraform-provider-sakuracloud/installation/#api)

```
$ export SAKURACLOUD_ACCESS_TOKEN=hogehoge
$ export SAKURACLOUD_ACCESS_TOKEN_SECRET=fugafuga
$ export SAKURACLOUD_ZONE=tk1a
```


## プラグインをインストール
外部プロバイダというものをインストールします。この外部プロバイダによって、公式が用意しているもの以外のクラウドサービスなども利用できるようになるようです。

プロバイダのバイナリは以下からダウンロードしてきます。今回はつい先日リリースされたばかりのエンハンスドロードバランサに対応した、`v2.0.0-alpha`を利用します。
[Releases · sacloud/terraform-provider-sakuracloud](https://github.com/sacloud/terraform-provider-sakuracloud/releases)

ホームディレクトリ下に専用のディレクトリを作成し、バイナリを展開します。

```
$ mkdir -p ~/.terraform.d/plugins/
$ cd ~/.terraform.d/plugins/
$ wget https://github.com/sacloud/terraform-provider-sakuracloud/releases/download/v2.0.0-alpha.3/terraform-provider-sakuracloud_2.0.0_linux-amd64.zip
$ ls
terraform-provider-sakuracloud_2.0.0_linux-amd64.zip
$ unzip terraform-provider-sakuracloud_2.0.0_linux-amd64.zip
Archive:  terraform-provider-sakuracloud_2.0.0_linux-amd64.zip
  inflating: terraform-provider-sakuracloud_v2.0.0_x5
$ ls
terraform-provider-sakuracloud_2.0.0_linux-amd64.zip  terraform-provider-sakuracloud_v2.0.0_x5
```

展開したプラグインをインストールします。
`.tf`ファイルを設置したディレクトリで`terraform init`コマンドを叩くことでインストール出来ます。

```
$ cd ~/terraform/create-server/
$ terraform init

Initializing provider plugins...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.sakuracloud: version = "~> 2.0"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
```

上記のように出てくればインストール完了です。

## 実行してみる
では、早速実行してみましょう。
まずは、`plan`コマンドで内容を確認します。

```
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.sakuracloud_archive.centos: Refreshing state...

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + sakuracloud_disk.disk01
      id:                               <computed>
      connector:                        "virtio"
      graceful_shutdown_timeout:        "60"
      name:                             "disk1"
      plan:                             "ssd"
      server_id:                        <computed>
      size:                             "20"
      source_archive_id:                "113100368797"
      tags.#:                           <computed>
      zone:                             <computed>

  + sakuracloud_server.server01
      id:                               <computed>
      additional_display_ipaddresses.#: <computed>
      cdrom_id:                         <computed>
      core:                             "1"
      disks.#:                          <computed>
      display_ipaddress:                <computed>
      dns_servers.#:                    <computed>
      gateway:                          <computed>
      graceful_shutdown_timeout:        "60"
      interface_driver:                 "virtio"
      ipaddress:                        <computed>
      macaddresses.#:                   <computed>
      memory:                           "1"
      name:                             "server01"
      nic:                              "shared"
      nw_address:                       <computed>
      nw_mask_len:                      <computed>
      packet_filter_ids.#:              <computed>
      password:                         <sensitive>
      private_host_name:                <computed>
      tags.#:                           "1"
      tags.0:                           "@virtio-net-pci"
      zone:                             <computed>


Plan: 2 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
```

`apply`してみます

```
$ terraform apply
data.sakuracloud_archive.centos: Refreshing state...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + sakuracloud_disk.disk01
      id:                               <computed>
      connector:                        "virtio"
      graceful_shutdown_timeout:        "60"
      name:                             "disk1"
      plan:                             "ssd"
      server_id:                        <computed>
      size:                             "20"
      source_archive_id:                "113100368797"
      tags.#:                           <computed>
      zone:                             <computed>

  + sakuracloud_server.server01
      id:                               <computed>
      additional_display_ipaddresses.#: <computed>
      cdrom_id:                         <computed>
      core:                             "1"
      disks.#:                          <computed>
      display_ipaddress:                <computed>
      dns_servers.#:                    <computed>
      gateway:                          <computed>
      graceful_shutdown_timeout:        "60"
      interface_driver:                 "virtio"
      ipaddress:                        <computed>
      macaddresses.#:                   <computed>
      memory:                           "1"
      name:                             "server01"
      nic:                              "shared"
      nw_address:                       <computed>
      nw_mask_len:                      <computed>
      packet_filter_ids.#:              <computed>
      password:                         <sensitive>
      private_host_name:                <computed>
      tags.#:                           "1"
      tags.0:                           "@virtio-net-pci"
      zone:                             <computed>


Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes # ← 実行しても良いか聞かれるのでyesとタイプ

  sakuracloud_disk.disk01: Creating...
  connector:                 "" => "virtio"
  graceful_shutdown_timeout: "" => "60"
  name:                      "" => "disk1"
  plan:                      "" => "ssd"
  server_id:                 "" => "<computed>"
  size:                      "" => "20"
  source_archive_id:         "" => "113100368797"
  tags.#:                    "" => "<computed>"
  zone:                      "" => "<computed>"
sakuracloud_disk.disk01: Still creating... (10s elapsed)
sakuracloud_disk.disk01: Still creating... (20s elapsed)
sakuracloud_disk.disk01: Still creating... (30s elapsed)
sakuracloud_disk.disk01: Still creating... (40s elapsed)
sakuracloud_disk.disk01: Still creating... (50s elapsed)
sakuracloud_disk.disk01: Still creating... (1m0s elapsed)
sakuracloud_disk.disk01: Still creating... (1m10s elapsed)
sakuracloud_disk.disk01: Still creating... (1m20s elapsed)
sakuracloud_disk.disk01: Creation complete after 1m28s (ID: 113100456223)
sakuracloud_server.server01: Creating...
  additional_display_ipaddresses.#: "" => "<computed>"
  cdrom_id:                         "" => "<computed>"
  core:                             "" => "1"
  disks.#:                          "" => "1"
  disks.0:                          "" => "113100456223"
  display_ipaddress:                "" => "<computed>"
  dns_servers.#:                    "" => "<computed>"
  gateway:                          "" => "<computed>"
  graceful_shutdown_timeout:        "" => "60"
  interface_driver:                 "" => "virtio"
  ipaddress:                        "" => "<computed>"
  macaddresses.#:                   "" => "<computed>"
  memory:                           "" => "1"
  name:                             "" => "server01"
  nic:                              "" => "shared"
  nw_address:                       "" => "<computed>"
  nw_mask_len:                      "" => "<computed>"
  packet_filter_ids.#:              "" => "<computed>"
  password:                         "<sensitive>" => "<sensitive>"
  private_host_name:                "" => "<computed>"
  tags.#:                           "" => "1"
  tags.0:                           "" => "@virtio-net-pci"
  zone:                             "" => "<computed>"
sakuracloud_server.server01: Still creating... (10s elapsed)
sakuracloud_server.server01: Still creating... (20s elapsed)
sakuracloud_server.server01: Still creating... (30s elapsed)
sakuracloud_server.server01: Still creating... (40s elapsed)
sakuracloud_server.server01: Still creating... (50s elapsed)
sakuracloud_server.server01: Still creating... (1m0s elapsed)
sakuracloud_server.server01: Creation complete after 1m4s (ID: 113100456235)

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

無事、サーバとディスクが作成されました🎉
![image.png](https://qiita-image-store.s3.amazonaws.com/0/182057/24d55017-208e-e78a-aa15-87831a6e0aeb.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/182057/1b5b1a4b-2684-bfa6-2951-6d07558ca5a9.png)

## 終わりに
結構めんどくさいのかなって思ったら、意外と大したことありませんでした。
これで簡単に大量のサーバを構築できますね！

## LINK
- [Terraform by HashiCorp](https://www.terraform.io/)
- [Terraform for さくらのクラウド](https://sacloud.github.io/terraform-provider-sakuracloud/)
- [sacloud/terraform-provider-sakuracloud: Terraform for さくらのクラウド | GitHub.com](https://github.com/sacloud/terraform-provider-sakuracloud)
- [Terraform for さくらのクラウド スタートガイド （第三回）〜さくらのクラウド上にインフラ構築〜 | さくらのナレッジ](https://knowledge.sakura.ad.jp/7660/)