LoginSignup
4
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-05-25

2017/05追記

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

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

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

連載目次

第1回:導入編

  • 概要
  • セットアップ
  • 実践 Step1:サーバー1台構成

第2回:実践編

  • 実践 Step2:構成/設定の変更
    • リソースの追加
    • リソースの変更
    • count構文
    • output機能

第3回:実践編2(当記事)

  • 実践 Step3:プロビジョニング
    • プロビジョニング接続設定
    • fileプロビジョニング
    • remote-execプロビジョニング
    • さくらのクラウドDNSリソースの利用

第4回:応用編

  • 実践 Step4:Web/DB 2-Tier構成
    • MySQLの利用
    • スイッチによるプライベートネットワークの構築
    • パケットフィルタ/シンプル管理:Slack通知の利用

第5回:応用編2

  • 実践 Step5:東京/石狩 マルチゾーン構成
    • 東京と石狩でマルチゾーン構成
    • GSLBによるゾーン間HA構成
    • MySQL レプリケーション + PHP(mysqlnd_ms)によるDBのクラスタリング
    • null_resourcetemplate_fileなどの特殊なリソース
    • tfファイルのリファクタリングとモジュール化

連載第3回です。
第1回から順番にお読みください。

第3回サンプルコード / 第2回との差分表示


実践 Step3:プロビジョニング

前回(第2回)は以下のような構成でした。

第2回での構成

servers02.png

サーバー2台、SSHを公開鍵認証で保護という構成でしたね。
今回はこの構成に以下のリソースを追加、さらにサーバーのプロビジョニングを行うことで、
サービスインできる体裁を整えていきます。

今回の構成

  • 外部からアクセスできるようにさくらのDNSにレコードを登録 (今回はサーバー2台分をDNSラウンドロビン構成)
  • 各サーバーにApache+PHPをインストールし、Webサーバーとして稼働させる
  • 稼働させるWebアプリは手元の作業用マシンからアップロード

servers03.png

実際に動作させてみるために、DNSには私の所有するドメインfe-bc.netを指定しています。
実際に実行する際は各自のドメインに読み替えてください。

準備

Webサーバー(Apache)で稼働させるWebアプリを用意します。
今回は単純にアクセスするとサーバーのIPアドレスと現在時刻を表示するだけのPHPアプリとします。

作業用ディレクトリ内にWebコンテンツを格納するディレクトリを作成し、その中にPHPファイルを作成します。

Webコンテンツ作成
$ mkdir webapps
$ vi webapps/index.php
#以下内容を記載
<?php
    date_default_timezone_set('Asia/Tokyo');
    echo "Terraform for さくらのクラウド スタートガイド用デモ". "<br /><br />";
    echo "IPアドレス:" . $_SERVER[ 'SERVER_ADDR' ] . "<br />";
    echo "時刻:" . date("Y/m/d H:i:s"). "<br />";

定義ファイル(tfファイル)の作成

それでは今回も定義ファイル(tfファイル)の編集を行いましょう。
前回までのtfファイルは以下のようになっていました。

sakura.tf(連載第2回での定義)
provider "sakuracloud" {
    token = "[ACCESS_TOKEN]"
    secret = "[ACCESS_TOKEN_SECRET]"
}

resource "sakuracloud_disk" "disk" {
    name = "${format("disk%02d" , count.index+1)}"
    source_archive_name = "CentOS 7.2 64bit"
    ssh_key_ids = ["${sakuracloud_ssh_key.mykey.id}"]
    disable_pw_auth = true
    count = 2
}

resource "sakuracloud_server" "server" {
    name = "${format("server%02d" , count.index+1)}"
    disks = ["${element(sakuracloud_disk.disk.*.id,count.index)}"]
    count = 2
}

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

output "global_ip" {
    value = "${join("\n" , formatlist("%s : %s" , sakuracloud_server.server.*.name , sakuracloud_server.server.*.base_nw_ipaddress))}"
}

今回もこれに追記していきましょう。

さくらのクラウドDNSリソースの定義

DNSレコードの定義を追記します。
対象のDNSゾーンは:fe-bc.net
WebサーバのFQDNは:web.fe-bc.netとします。
2台分のAレコードを記載しましょう。

sakura.tf(DNS)
resource "sakuracloud_dns" "dns" {
    zone = "fe-bc.net"
    records = {
        name = "web"
        type = "A"
        value = "${sakuracloud_server.server.0.base_nw_ipaddress}"
    }
    records = {
        name = "web"
        type = "A"
        value = "${sakuracloud_server.server.1.base_nw_ipaddress}"
    }
}

余談:recordsの書き方について

本当は以下のように書きたいところなんですが、、

sakura.tf(DNS)未サポートな書き方
# 今はこの書き方はできない!!
resource "sakuracloud_dns" "dns" {
    zone = "fe-bc.net"
    records = {
        count = 2
        name = "web"
        type = "A"
        value = "${element(sakuracloud_server.server.*.base_nw_ipaddress , count.index)}"
    }
}

現在Terraformではネストしたリソースでのcount構文はサポートされません。
2016年5月25日現在、こちらで議論中です。
別解としてsakuracloud_dnsリソースとsakuracloud_dns_recordリソースを分けるように
ソース改修という手もあるのですが、さくらのクラウドAPI側でDNS、GSLBなどは並列実行時のデータ消失の危険性があるため、現状のAPI仕様ではこの対応はしたくないと思っています。

プロビジョニング

いよいよプロビジョニングの定義を行ってみましょう。
今回は

  • 1 : サーバーにはSSHで接続
  • 2 : yumでApache+PHPをインストール
  • 3 : 手元の作業用マシンで作ったWebコンテンツをアップロード

を行います。

tfファイルに以下のように記載しましょう。

sakura.tf(SSH接続定義)

resource sakuracloud_server "server"{
    name = "${format("server%02d" , count.index+1)}"
    disks = ["${element(sakuracloud_disk.disk.*.id,count.index)}"]
    count = 2

    # 1: サーバーにはSSHで接続
    connection {
       user = "root"
       host = "${self.base_nw_ipaddress}"
       private_key = "${file("./id_rsa")}"
    }

    # 2: yumでapache+PHPのインストール
        provisioner "remote-exec" {
        inline = [
          "yum install -y httpd httpd-devel php php-mbstring",
          "systemctl restart httpd.service",
          "systemctl enable httpd.service",
          "systemctl stop firewalld.service",
          "systemctl disable firewalld.service"
        ]
   }

   # 3: Webコンテンツをアップロード
   provisioner "file" {
        source = "webapps/"
        destination = "/var/www/html"
   }
}

プロビジョニング時の接続方法定義

connectionブロックにてプロビジョニングの際の接続方法を定義しています。
設定できる値の一覧などはこちらのTerraoformドキュメントを参照してください。

プロビジョニング定義

続いてのprovisionerブロックでプロビジョニング手順を定義していきます。
現在定義できるのは以下のものです。ansibleは直接はサポートされていませんが、
local-execを駆使することで対応可能ですね。

  • chef : chefでプロビジョニング!
  • file : 作業用マシンからファイルのアップロード
  • local-exec : 作業用マシンでのコマンド実行、例えばVPCルーターとの間でVPNセッション張るとか。
  • remote-exec : 対象サーバー上でのコマンド実行

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

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

sakura.tf(全体)
provider "sakuracloud" {
    token = "[ACCESS_TOKEN]"
    secret = "[ACCESS_TOKEN_SECRET]"
}

resource "sakuracloud_disk" "disk" {
    name = "${format("disk%02d" , count.index+1)}"
    source_archive_name = "CentOS 7.2 64bit"
    ssh_key_ids = ["${sakuracloud_ssh_key.mykey.id}"]
    disable_pw_auth = true
    count = 2
}

resource "sakuracloud_server" "server" {
    name = "${format("server%02d" , count.index+1)}"
    disks = ["${element(sakuracloud_disk.disk.*.id,count.index)}"]
    count = 2
    # 1: サーバーにはSSHで接続
    connection {
       user = "root"
       host = "${self.base_nw_ipaddress}"
       private_key = "${file("./id_rsa")}"
    }

    # 2: yumでapache+PHPのインストール
        provisioner "remote-exec" {
        inline = [
          "yum install -y httpd httpd-devel php php-mbstring",
          "systemctl restart httpd.service",
          "systemctl enable httpd.service",
          "systemctl stop firewalld.service",
          "systemctl disable firewalld.service"
        ]
   }

   # 3: Webコンテンツをアップロード
   provisioner "file" {
        source = "webapps/"
        destination = "/var/www/html"
   }

}

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

resource "sakuracloud_dns" "dns" {
    zone = "fe-bc.net"
    records = {
        name = "web"
        type = "A"
        value = "${sakuracloud_server.server.0.base_nw_ipaddress}"
    }
    records = {
        name = "web"
        type = "A"
        value = "${sakuracloud_server.server.1.base_nw_ipaddress}"
    }
}

output "global_ip" {
    value = "${join("\n" , formatlist("%s : %s" , sakuracloud_server.server.*.name , sakuracloud_server.server.*.base_nw_ipaddress))}"
}

terraformコマンド実施!

ではこれまで同様terraoform planで確認してterraform applyを、、と言いたいところなのですが、
残念ながら現在のTerraformは、すでに存在するリソースへのプロビジョニングはサポートされません。
詳しくはこちらのIssueが該当しているようです。

というわけで、今回はまずリソースの削除を行ってから改めて作成していきましょう。

terraform destroy:リソースの削除実施

terraform destroyを実行してみましょう。

terraform_destroy
$ terraform destroy
Do you really want to destroy?
  Terraform will delete all your managed infrastructure.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes     #削除する場合はyesを入力してenter

sakuracloud_ssh_key.mykey: Refreshing state... (ID: 112800522836)
sakuracloud_disk.disk.0: Refreshing state... (ID: 112800522837)
sakuracloud_disk.disk.1: Refreshing state... (ID: 112800522838)
sakuracloud_server.server.0: Refreshing state... (ID: 112800522843)
sakuracloud_server.server.1: Refreshing state... (ID: 112800522842)
sakuracloud_server.server.0: Destroying...
sakuracloud_server.server.1: Destroying...
sakuracloud_server.server.0: Still destroying... (10s elapsed)
sakuracloud_server.server.1: Still destroying... (10s elapsed)
sakuracloud_server.server.0: Destruction complete
sakuracloud_server.server.1: Destruction complete
sakuracloud_disk.disk.0: Destroying...
sakuracloud_disk.disk.1: Destroying...
sakuracloud_disk.disk.0: Destruction complete
sakuracloud_disk.disk.1: Destruction complete
sakuracloud_ssh_key.mykey: Destroying...
sakuracloud_ssh_key.mykey: Destruction complete

Apply complete! Resources: 0 added, 0 changed, 5 destroyed.

削除されましたね?では改めてplanapplyを実行してみましょう。

無事緑色のApply complete!が表示されましたか?
complete01.png

では動作確認の前にDNSレコードの仕上げをしましょう。

さくらのDNSの設定

今回はfe-bc.netというゾーンのDNSサーバにさくらのクラウドDNSを用い、
Aレコードを2件登録しました。

あとはドメインfe-bc.netのwhoisのネームサーバーをさくらのクラウドのDNSサーバに設定すれば完了です。
whoisのネームサーバー登録方法については各レジストラのマニュアルなどを参照ください。
なお、さくらで取得しているドメインの場合は以下のページを参照してください。
さくらで取得したドメインのネームサーバ情報を変更

参考:ネームサーバ情報の参照

terraform showコマンドで、whoisのネームサーバーに登録するDNSサーバー名を参照できます。
dns_whois.png

DNS設定の確認

以下コマンドでDNSの確認をしておきましょう。

DNS確認
$ dig web.fe-bc.net.

以下のようにさくらのクラウドで自動で割り当てられたIPアドレスが取得できていればOKです。

dig.png

動作確認(web)

ではブラウザでhttp://web.fe-bc.net/index.phpへアクセスしてみます。

以下のような画面が表示されればOKです。
browser.png

何度かリロードすればDNSラウンドロビンされている様子も確認できるかと思います。

まとめ

今回は

  • プロビジョニング時の接続定義方法
  • リモートサーバーでのコマンド実行によるプロビジョニング
  • ローカルファイルのアップロードでのプロビジョニング

を扱いました。また、さくらのクラウドのDNSリソースについても扱ってみました。
terraform applyすればWebコンテンツの提供ができるようになりましたね!
次回はいよいよ本番投入を見据えたWeb/DB2層構造でのインフラ構築を行います。
また、セキュリティや監視など本番運用に必要なリソースの追加もしていきます。
お楽しみに :bangbang:

次回:実践 Step4:Web/DB 2-Tier構成

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4