Ore no homepage
chefを捨ててシェルスクリプトにした
一部のサブシステムの構築で、プロビジョニングツールを捨ててみた。じゃあどうするのかというとシェルスクリプトでやる。今回はこのやりかたが一番楽できるような気がしたので試している。
具体的にはPackerからシェルスクリプトとServerspecを実行してAMIを煮込む。おいしくできあがったらそいつから構築。もしミドルウェアより下の層のコンフィグ類に変更があったらまた煮込む。構築する。新しい方に切り替える。つまり”捨てるインフラ”にする。
プラットフォームはAWS。
Packer + シェルスクリプト + Serverspec
今回は以下の要件, 方針&ぼやき。
- 要件:このサブシステムはトラフィックが少なく、機能も複雑ではないのでミドルウェアより下の層でやることはほとんどない。なのでシェルスクリプトでやっても大して面倒ではないはず。やることはnginxとnodejsと監視エージェントのパッケージをインストール -> コンフィグを撒く -> 必要なプロセスを起動…ってだけだ。
- 方針:冒頭で述べた通りコンフィグ類の変更時は捨てる。横文字で言うとDisposable Infrastructureってやつ?
- ぼやき:プロビジョニングツールに疲れた。
- たぶん:chefわからん人は結構いるかもしれないけどシェルスクリプトだったら誰でもわかるだろう。もしかしたらこっちのやりかたの方が引き継ぎもしやすいかもしれないし、保守もしやすいかもしれない。
こんな感じ
以下のようにして作っている。
1 2 3 4 5 | export AWS_ACCESS_KEY_ID=XXXXXX export AWS_SECRET_ACCESS_KEY=XXXXXX packer build template.json |
template.jsonは次の通り。手を加えたOSのコンフィグ(assets/os_settings)、sshログインのための公開鍵とgithubのプライベートリポジトリからcloneするための鍵(assets/keys)、ミドルウェアのコンフィグ類(assets/XXXX/production)、パッケージ類(nodejsのrpm)、シェルスクリプト内で使う環境変数を記述したファイル(base.env)、serverspecをアップロードする。そしてシェルスクリプト(base.sh, production.sh, production_spec.sh)を実行する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | { "variables": { "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}", "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}" }, "builders": [{ "access_key": "{{user `aws_access_key`}}", "secret_key": "{{user `aws_secret_key`}}", "region": "XXXX", "source_ami": "ami-XXXX", "vpc_id": "vpc-XXXX", "subnet_id": "subnet-XXXX", "type": "amazon-ebs", "instance_type": "XXXX", "ssh_username": "XXXX", "ami_users": ["XXXX"], "ami_name": "XXXX" }], "provisioners": [{ "type": "file", "source": "assets/os_settings", "destination": "/tmp/os_settings" }, { "type": "file", "source": "assets/keys", "destination": "/tmp/keys" }, { "type": "file", "source": "assets/XXXX/production", "destination": "/tmp/production" }, { "type": "file", "source": "assets/rpms/node-XXXX.x86_64.rpm", "destination": "/tmp/node-XXXX.x86_64.rpm" }, { "type": "file", "source": "scripts/base.env", "destination": "/tmp/base.env" }, { "type": "file", "source": "serverspec", "destination": "/tmp/serverspec" }, { "type": "shell", "scripts": ["scripts/base.sh", "scripts/XXXX/production.sh", "scripts/XXXX/production_spec.sh"], "execute_command": "{{ .Vars }} sudo -E sh '{{ .Path }}'" }] } |
base.sh, production.sh, production_spec.sh
base.shはアプリケーション用のユーザの作成、タイムゾーン、ulimit、鍵、sudoersなど主にOSの設定を整えている。
production.shはnginx入れてコンフィグ撒く、nodejs入れてボワー、datadog入れてコンフィグ撒く、sensu入れてコンフィグ撒くという処理をする(下にコードを晒す)。少しトリッキーなのは、rc.localにヒアドキュメントを突っ込んでいる。これはインスタンス起動時にそのインスタンスのホスト名でSensuのコンフィグを生成したいため。
production_spec.shはuploadしたserverspecのディレクトリ(/tmp/serverspec)に移動してbundle installしてserverspecを実行する。
例になるが、production.shは次のような形になっている。やっていることはパッケージを入れて、アップロードしたコンフィグを撒いているだけであることがわかると思う。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | source /tmp/base.env echo '### install nginx ###' yum install -y nginx install -o root -g root -m 0644 /tmp/production/nginx/nginx.conf /etc/nginx/ /etc/init.d/nginx start chkconfig nginx on echo '### delete default configs ###' rm -f /etc/nginx/conf.d/default.conf rm -f /etc/nginx/conf.d/example_ssl.conf echo '### install nodejs ###' yum install -y /tmp/node-XXXX.x86_64.rpm /opt/node/bin/npm install -g bower /opt/node/bin/npm install -g grunt-cli /opt/node/bin/npm install -g forever echo "### install datadog agent ###" DD_API_KEY=XXXXX bash -c "$(curl -L https://raw.githubusercontent.com/DataDog/dd-agent/master/packaging/datadog-agent/source/install_agent.sh)" install -o dd-agent -g root -m 0644 /tmp/production/datadog/nginx.yaml /etc/dd-agent/conf.d/ chkconfig datadog-agent on echo '### install sensu-client ###' install -o root -g root -m 0644 /tmp/production/sensu/sensu.repo /etc/yum.repos.d/ yum clean all yum install -y sensu nmap rm -f /etc/sensu/client.json install -o root -g root -m 0644 /tmp/production/sensu/sensu /etc/default/ install -o root -g root -m 0644 /tmp/production/sensu/config.json /etc/sensu/ install -o root -g root -m 0755 /tmp/production/sensu/plugins/* /etc/sensu/plugins/ install -o root -g root -m 0755 -d /etc/sensu/ssl install -o root -g root -m 0644 /tmp/production/sensu/ssl/* /etc/sensu/ssl/ /etc/init.d/sensu-client stop chkconfig sensu-client off echo '### edit rc.local to make the sensu client config after creating instance ###' cat << "EOS" >> /etc/rc.local $(cat << EOT > /etc/sensu/conf.d/client.json { "client": { "name": "`hostname`", "address": "`hostname`", "subscriptions": ["common","http", "node"] }, "keepalive": { "thresholds": { "critical": 60, "occurrence": 3 }, "refresh": 300 } } EOT) /etc/init.d/sensu-client start chkconfig sensu-client on EOS |
rc.localのところがちょっと痒いが、この程度だったらシェルスクリプトで十分じゃないかな。運用が辛くなったらchefなりansibleなりitamaeなりをやっぱ導入すればいいし。まあそれで解決されるかはわからんけど。
コンテナは使わないのか?
コンテナも動向を追ったり検証してはいる。ちょっと今は他にやることがあって手が出しにくい。
そういえば
fluentd入れ忘れた。作りなおさなきゃ。
おわり
Information
welcome!Top Posts
- - 開発支援系のサービスが充実しすぎて転職か廃業を考えた [33,041 views]
- - MySQL ibdata1が肥大化する理由(記事の意訳) [11,908 views]
- - vm.swappiness=0は重要 [10,714 views]
- - about [10,335 views]
- - serverspec インフラ層のテスト項目を考える [9,895 views]
- - MySQL バイナリログを使ったデータリカバリ [9,407 views]
- - Cassandraメモその1(インストール、データモデル、データ操作について) [7,438 views]
- - Mac OSX開発環境構築メモ、便利なツールとか [7,078 views]
- - knifeクライアントの設定とchefの実行 [6,398 views]
- - OSXのdashboardを使うと監視が捗るかもしれない [6,256 views]
Recent Posts
Archives
- 2015年4月 (1)
- 2015年2月 (1)
- 2015年1月 (1)
- 2014年12月 (2)
- 2014年11月 (1)
- 2014年10月 (1)
- 2014年9月 (2)
- 2014年8月 (3)
- 2014年6月 (2)
- 2014年5月 (3)
- 2014年4月 (2)
- 2014年3月 (3)
- 2014年1月 (1)
- 2013年12月 (3)
- 2013年11月 (2)
- 2013年10月 (3)
- 2013年8月 (1)
- 2013年7月 (2)
- 2013年6月 (1)
- 2013年5月 (3)
- 2013年4月 (3)
- 2013年3月 (4)
- 2013年2月 (2)
- 2013年1月 (2)
- 2012年12月 (3)
- 2012年11月 (1)
- 2012年10月 (4)
- 2012年9月 (1)
- 2012年7月 (3)
- 2012年6月 (2)
- 2012年5月 (1)
- 2012年4月 (2)
- 2012年3月 (1)
- 2012年2月 (1)
- 2012年1月 (1)
- 2011年11月 (4)