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_resource
やtemplate_file
などの特殊なリソース - tfファイルのリファクタリングとモジュール化
連載第3回です。
第1回から順番にお読みください。
実践 Step3:プロビジョニング
前回(第2回)は以下のような構成でした。
第2回での構成
サーバー2台、SSHを公開鍵認証で保護という構成でしたね。
今回はこの構成に以下のリソースを追加、さらにサーバーのプロビジョニングを行うことで、
サービスインできる体裁を整えていきます。
今回の構成
- 外部からアクセスできるように
さくらのDNS
にレコードを登録
(今回はサーバー2台分をDNSラウンドロビン構成) - 各サーバーにApache+PHPをインストールし、Webサーバーとして稼働させる
- 稼働させるWebアプリは手元の作業用マシンからアップロード
実際に動作させてみるために、DNSには私の所有するドメインfe-bc.net
を指定しています。
実際に実行する際は各自のドメインに読み替えてください。
準備
Webサーバー(Apache)で稼働させるWebアプリを用意します。
今回は単純にアクセスするとサーバーのIPアドレスと現在時刻を表示するだけのPHPアプリとします。
作業用ディレクトリ内にWebコンテンツを格納するディレクトリを作成し、その中にPHPファイルを作成します。
$ 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ファイルは以下のようになっていました。
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レコードを記載しましょう。
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
の書き方について
本当は以下のように書きたいところなんですが、、
# 今はこの書き方はできない!!
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ファイルに以下のように記載しましょう。
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ファイルは以下のようになっているはずです。
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
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.
削除されましたね?では改めてplan
とapply
を実行してみましょう。
無事緑色のApply complete!
が表示されましたか?
では動作確認の前にDNSレコードの仕上げをしましょう。
さくらのDNSの設定
今回はfe-bc.net
というゾーンのDNSサーバにさくらのクラウドDNSを用い、
Aレコードを2件登録しました。
あとはドメインfe-bc.net
のwhoisのネームサーバーをさくらのクラウドのDNSサーバに設定すれば完了です。
whoisのネームサーバー登録方法については各レジストラのマニュアルなどを参照ください。
なお、さくらで取得しているドメインの場合は以下のページを参照してください。
さくらで取得したドメインのネームサーバ情報を変更
参考:ネームサーバ情報の参照
terraform show
コマンドで、whoisのネームサーバーに登録するDNSサーバー名を参照できます。
DNS設定の確認
以下コマンドでDNSの確認をしておきましょう。
$ dig web.fe-bc.net.
以下のようにさくらのクラウドで自動で割り当てられたIPアドレスが取得できていればOKです。
動作確認(web)
ではブラウザでhttp://web.fe-bc.net/index.php
へアクセスしてみます。
何度かリロードすればDNSラウンドロビンされている様子も確認できるかと思います。
まとめ
今回は
- プロビジョニング時の接続定義方法
- リモートサーバーでのコマンド実行によるプロビジョニング
- ローカルファイルのアップロードでのプロビジョニング
を扱いました。また、さくらのクラウドのDNSリソースについても扱ってみました。
terraform apply
すればWebコンテンツの提供ができるようになりましたね!
次回はいよいよ本番投入を見据えたWeb/DB2層構造でのインフラ構築を行います。
また、セキュリティや監視など本番運用に必要なリソースの追加もしていきます。
お楽しみに