1. eigo_s

    Posted

    eigo_s
Changes in title
+terraformのnull_resourceが便利だよ!という話
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,191 @@
+# はじめに
+この記事は、[dwango advent calender](http://qiita.com/advent-calendar/2016/dwango)の12日目の記事です!
+ギリギリ間に合わない感じになってしまいましたが、気にせずやっていきます(☝◞‸◟)☝
+
+# terraformとは?
+もう説明不要ですよね!
+awsやGCPやopenstackなどなどの環境をコード化できる構成管理ツールです。
+
+# terraformのnull_resourceとは?
+その名の通りですが、何もしないresourceです。
+他のresourceができあがったことをトリガーとして、プロビジョニングを行うことができます。
+ドキュメントは[こちら](https://www.terraform.io/docs/provisioners/null_resource.html)です。
+
+
+# 何が便利なのか?
+例えばの話ですが、EC2インスタンスが起動するまで、EC2のpublic_ipやprivate_ipはわからなかったりします。
+そのため、IPがわかっていることを前提とした、クラスタ系の操作などはインスタンスが作成された後でしか実行することができません。
+ですが、null_resourceを利用すると、別のresource(EC2インスタンスやRDSインスタンスなど)をトリガーとして、プロビジョニングを行えます。
+これは、terraformをapplyするだけで、プロビジョニング済で利用できる、ということになります。
+
+# ということで、自分の担当プロダクトで行っている実例
+今回は、自分が担当しているプロダクトで実際に利用している例をもとに説明していこうと思います。
+コードは[こちら](https://github.com/eigo-s/terraform-example/tree/master/null_resource_rds)にあげました。
+
+## どうしてnull_resourceが必要だったのか?
+オンプレ→AWSという移行案件だったのですが、フロントで利用しているmysqlと、管理ツールで利用しているmysqlと2系統ありました。
+フロントの方で利用しているmysqlは、アクセスもデータ量も少なく、管理ツール用とあわせた方がmysqlの管理コストも低くなり良いだろう、と思った次第でした。
+元々は、chefでmysqlをインストールしdatabaseを作成していましたが、RDSになったことで、chefでdatabaseの作成ができなくなったため、利用することにしました。
+※[mysql provider](https://www.terraform.io/docs/providers/mysql/index.html)も当時存在していたのですが、うまいこと動作せず、リリースまで時間もなかったためこのようにしました(◞‸◟)
+
+## 実際の肝となるコード部分
+コードとしては下記のような感じです。
+
+```provision.tf
+resource "null_resource" "create-second-db" {
+ triggers {
+ endpoint = "${aws_db_instance.rds-master.endpoint}"
+ }
+
+ provisioner "remote-exec" {
+ connection {
+ type = "ssh"
+ host = "${aws_instance.bastion.public_dns}"
+ user = "${var.bastion_user}"
+ private_key = "${file("${path.module}/bastion.pem")}"
+ }
+
+ inline = [
+ "sudo yum -y install mysql",
+ "mysql -u${var.rds_username} -p${var.rds_password} -h${aws_db_instance.rds-master.address} -e\"create database ${var.rds_second_db};\"",
+ ]
+ }
+}
+```
+
+1. null_resourceを利用し、RDSのmasterが作成されたことをトリガーとする
+2. 踏み台サーバーにsshで接続し、mysql cliをインストールする
+3. terraformで利用したRDSのuser/password変数を元に、mysql cliでRDSのmasterに接続し、2つ目のdatabaseを作成する
+
+という流れとなります。
+
+実行結果としては下記のような感じです。
+
+```console
+null_resource.create-second-db: Creating...
+ triggers.%: "" => "1"
+ triggers.endpoint: "" => "rds-master.cffuvhvco6ag.ap-northeast-1.rds.amazonaws.com:3306"
+null_resource.create-second-db: Provisioning with 'remote-exec'...
+null_resource.create-second-db (remote-exec): Connecting to remote host via SSH...
+null_resource.create-second-db (remote-exec): Host: ec2-52-68-75-114.ap-northeast-1.compute.amazonaws.com
+null_resource.create-second-db (remote-exec): User: ec2-user
+null_resource.create-second-db (remote-exec): Password: false
+null_resource.create-second-db (remote-exec): Private key: true
+null_resource.create-second-db (remote-exec): SSH Agent: true
+null_resource.create-second-db (remote-exec): Connected!
+null_resource.create-second-db (remote-exec): Loaded plugins: priorities, update-motd,
+null_resource.create-second-db (remote-exec): : upgrade-helper
+null_resource.create-second-db (remote-exec): amzn-main/latest | 2.1 kB 00:00
+null_resource.create-second-db (remote-exec): amzn-updates/lat | 2.3 kB 00:00
+null_resource.create-second-db (remote-exec): Resolving Dependencies
+null_resource.create-second-db (remote-exec): --> Running transaction check
+null_resource.create-second-db (remote-exec): ---> Package mysql.noarch 0:5.5-1.6.amzn1 will be installed
+null_resource.create-second-db (remote-exec): --> Processing Dependency: mysql55 >= 5.5 for package: mysql-5.5-1.6.amzn1.noarch
+null_resource.create-second-db (remote-exec): --> Running transaction check
+null_resource.create-second-db (remote-exec): ---> Package mysql55.x86_64 0:5.5.52-1.13.amzn1 will be installed
+null_resource.create-second-db (remote-exec): --> Processing Dependency: real-mysql55-libs(x86-64) = 5.5.52-1.13.amzn1 for package: mysql55-5.5.52-1.13.amzn1.x86_64
+null_resource.create-second-db (remote-exec): --> Processing Dependency: mysql-config for package: mysql55-5.5.52-1.13.amzn1.x86_64
+null_resource.create-second-db (remote-exec): --> Running transaction check
+null_resource.create-second-db (remote-exec): ---> Package mysql-config.x86_64 0:5.5.52-1.13.amzn1 will be installed
+null_resource.create-second-db (remote-exec): ---> Package mysql55-libs.x86_64 0:5.5.52-1.13.amzn1 will be installed
+null_resource.create-second-db (remote-exec): --> Finished Dependency Resolution
+
+null_resource.create-second-db (remote-exec): Dependencies Resolved
+
+null_resource.create-second-db (remote-exec): ========================================
+null_resource.create-second-db (remote-exec): Package Arch Version
+null_resource.create-second-db (remote-exec): Repository Size
+null_resource.create-second-db (remote-exec): ========================================
+null_resource.create-second-db (remote-exec): Installing:
+null_resource.create-second-db (remote-exec): mysql noarch 5.5-1.6.amzn1
+null_resource.create-second-db (remote-exec): amzn-main 2.7 k
+null_resource.create-second-db (remote-exec): Installing for dependencies:
+null_resource.create-second-db (remote-exec): mysql-config
+null_resource.create-second-db (remote-exec): x86_64 5.5.52-1.13.amzn1
+null_resource.create-second-db (remote-exec): amzn-updates 49 k
+null_resource.create-second-db (remote-exec): mysql55 x86_64 5.5.52-1.13.amzn1
+null_resource.create-second-db (remote-exec): amzn-updates 7.5 M
+null_resource.create-second-db (remote-exec): mysql55-libs
+null_resource.create-second-db (remote-exec): x86_64 5.5.52-1.13.amzn1
+null_resource.create-second-db (remote-exec): amzn-updates 815 k
+
+null_resource.create-second-db (remote-exec): Transaction Summary
+null_resource.create-second-db (remote-exec): ========================================
+null_resource.create-second-db (remote-exec): Install 1 Package (+3 Dependent packages)
+
+null_resource.create-second-db (remote-exec): Total download size: 8.4 M
+null_resource.create-second-db (remote-exec): Installed size: 31 M
+null_resource.create-second-db (remote-exec): Downloading packages:
+null_resource.create-second-db (remote-exec): (1/4): mysql-5.5 | 2.7 kB 00:00
+null_resource.create-second-db (remote-exec): (2/4): mysql-con | 49 kB 00:00
+null_resource.create-second-db (remote-exec): (3/4): mysql55-5 | 7.5 MB 00:00
+null_resource.create-second-db (remote-exec): (4/4): mysql55-l | 815 kB 00:00
+null_resource.create-second-db (remote-exec): ----------------------------------------
+null_resource.create-second-db (remote-exec): Total 36 MB/s | 8.4 MB 00:00
+null_resource.create-second-db (remote-exec): Running transaction check
+null_resource.create-second-db (remote-exec): Running transaction test
+null_resource.create-second-db (remote-exec): Transaction test succeeded
+null_resource.create-second-db (remote-exec): Running transaction
+null_resource.create-second-db (remote-exec): Installing : mysql-co [ ] 1/4
+null_resource.create-second-db (remote-exec): Installing : mysql-co [####### ] 1/4
+null_resource.create-second-db (remote-exec): Installing : mysql-config-5.5.5 1/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [ ] 2/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [# ] 2/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [## ] 2/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [### ] 2/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [#### ] 2/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [##### ] 2/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [###### ] 2/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [####### ] 2/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [######## ] 2/4
+null_resource.create-second-db (remote-exec): Installing : mysql55-libs-5.5.5 2/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [ ] 3/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [# ] 3/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [## ] 3/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [### ] 3/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [#### ] 3/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [##### ] 3/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [###### ] 3/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [####### ] 3/4
+null_resource.create-second-db (remote-exec): Installing : mysql55- [######## ] 3/4
+null_resource.create-second-db (remote-exec): Installing : mysql55-5.5.52-1.1 3/4
+null_resource.create-second-db (remote-exec): Installing : mysql-5. [ ] 4/4
+null_resource.create-second-db (remote-exec): Installing : mysql-5.5-1.6.amzn 4/4
+null_resource.create-second-db (remote-exec): Verifying : mysql-5.5-1.6.amzn 1/4
+null_resource.create-second-db (remote-exec): Verifying : mysql55-libs-5.5.5 2/4
+null_resource.create-second-db (remote-exec): Verifying : mysql-config-5.5.5 3/4
+null_resource.create-second-db (remote-exec): Verifying : mysql55-5.5.52-1.1 4/4
+
+null_resource.create-second-db (remote-exec): Installed:
+null_resource.create-second-db (remote-exec): mysql.noarch 0:5.5-1.6.amzn1
+
+null_resource.create-second-db (remote-exec): Dependency Installed:
+null_resource.create-second-db (remote-exec): mysql-config.x86_64 0:5.5.52-1.13.amzn1
+null_resource.create-second-db (remote-exec): mysql55.x86_64 0:5.5.52-1.13.amzn1
+null_resource.create-second-db (remote-exec): mysql55-libs.x86_64 0:5.5.52-1.13.amzn1
+
+null_resource.create-second-db (remote-exec): Complete!
+null_resource.create-second-db: Creation complete
+```
+
+
+実際は、他にもたくさんコンポーネントがあったりしますが、terraformのapplyを行った後でアプリケーションが乗る以前に状態を全て作ることができるのは、terraformの便利さを感じることができる瞬間でした。
+そんなこんなで、個人的にはnull_resourceをもっと有効活用し、手動で何かを実施する、みたいなことをガンガン減らし、terraform applyだけで0からそのシステムの環境ができる状態を作っていきたいな、と思うのでした。
+
+
+# 余談1
+terraform 0.7.8以降では、aws_instanse + aws_eipの組み合わせの場合に、applyの度に、インスタンスが再作成されるというバグ?が存在します。
+[issue](https://github.com/hashicorp/terraform/issues/9811)もあがっており、修正されてる[pull request](https://github.com/hashicorp/terraform/pull/10078)も出ていますが、まだmergeされていないため未リリースとなるので、気をつけて下さい。
+自分の場合は、元々0.7.8で利用できるようになった、pagerduty providerやAWS WAF resourceを利用したかったため、0.7.8の検証を行っていたところ、ハマってしまった次第でした(◞‸◟)
+先日のaws re:invent2016でhashicorpブースにお邪魔した際に、terraformのコミッターの方がいらしていて、「このissueで困ってるよ!」と伝えることができたので、早いところ治らないかなー、と心待ちにしていたりします。
+
+# 余談2
+terraformの[CHANGELOG.md](https://github.com/hashicorp/terraform/blob/master/CHANGELOG.md)をだいたい一日一回見る、みたいなことを日課にしているのですが、次メジャーバージョンアップ(0.8)で取り込まれるproviderで興味深い物がありました。
+それは、 external providerというものです。
+詳しくは、[こちらのpull request](https://github.com/hashicorp/terraform/pull/8768)を見ていただくと良いのですが、簡単にいうと、「実行したスクリプトのプログラムの実行結果を渡すことができる」というもののようです。
+pull requestのように、実行結果の値を利用して、何かを行う、みたいなことの自由度があがりそうですね!
+
+
+
+
+