OpsWorks は AWS の1サービスで、Chef を使ったプロビジョニングを楽に行ってくれるサービスです。今のプロジェクトでは、自前の Ansible から OpsWorks へ移行しているため、社内で OpsWorks について紹介しました。
スライドの中では、実際に使ってみた所感も書いているので、このエントリーではその点について少し追記したいと思います。
[toc]
発表資料:"OpsWorks で簡単プロビジョニング"
※ 社内での紹介は、プロジェクトでの設定例やデモも交えたのですが、ここでは省いています。
AWS OpsWorks のよいところ
インスタンスの状況や、レイヤに割り当たっている ELB が可視化される
OpsWorks を使う事で、その VPC にどんなレイヤが存在するのか、何台立ち上がっているのかなどの情報が可視化されます。特に、レシピの実行に失敗した場合にインスタンスが failed の状態になるのが便利です。
ネットワークは表し得ませんが、どんなタイプのインスタンスがいるかが分かりやすいので、開発や運用に新しく人が加わるときに敷居が低くなるかなと期待しています。
Configure イベントで他インスタンスに通知できるのが面白い
Configure イベントは、スタック内でインスタンスが増減した場合に全インスタンスが移行する LifeCycle です。
Configure イベントのおかげで、OpsWorks 内のインスタンスはスタック全体で1つのアプリケーションを構築する有機的な動きをしてくれます。Chef だけではプロビジョニングツールですが、ここまでいくとオーケストレーションツールとしても使えそうです。Serf なんかで実現していることも、Configure や Deploy, Undeploy のイベントを組み合わせれば実現できそうです。
Nagios, Sensu などの監視ツールとも相性がいいので、インスタンスによって設定ファイルの更新が必要なものを Configure イベントに入れておくとよいです。
インスタンスではなく、レイヤに注意が向く
クラウド運用に慣れていないと、インスタンスの状態を保存した AMI を中心とした運用になるかと思いますが、インスタンス内でアドホックな設定を直接設定したあとに AMI 作成をしたりするなど、次第に何が正しい状態か分からなくなりがちです。
OpsWorks ではレイヤに対してレシピを登録するので、インスタンスにはあまり気が向かず、私の携わっているプロジェクトでは、気軽にインスタンスを入れ替えられるようになりました。AWS は強制メンテナンスがあるので、メンテナンス対象になったインスタンスを捨てて、すぐさま新しいインスタンスに入れ替えが出来ると精神的にとても楽です。
全レシピがたびたび実行されると、レシピに埃がかぶらないのもよいところ。
AWS OpsWorks の微妙なところ
レシピの動作確認中の待ちが多い
ローカル環境で Vagrant を利用して開発されている方もいるようでしたが、AWS 側(というか前身の Scalarium)でいろいろと手を加えているようで私には面倒だったので、検証用のブランチと本番用のブランチを用意して、それぞれで OpsWorks のスタックを作成して検証していました。
しかし、OpsWorks は新規 Amazon AMI から初期設定を行うため、大量の yum update に時間が掛かるのか、初回起動は5分〜10分ほど待たなければなりません。起動中のインスタンスへのレシピ実行も、固定で数分は掛かりますので、断続的に待ち時間が発生するのが少々煩わしいです。
Amazon AMI だけでなく、カスタム AMI も使えるので、最低限の初期設定をしたものを用意しておくのもよいかもしれませんが、その管理をし始めると OpsWorks(Chef)のうまみが薄れるので微妙なところです。
Load-based インスタンスの設定が原始的
OpsWorks のスケーリングには AutoScaling は使用できません。その変わりに、起動許可する最大インスタンス数まであらかじめ登録するという、少し妙な設定の仕方をします。
先ほど述べたように初回起動は5分10分掛かるので、登録したインスタンスは Setup イベントだけは済ませておかないと、いざスケールさせるときに10分も20分も待たなければなりません。しかしそのためには自前で最大負荷を掛ける必要があり、かなりめんどくさいです。いけてない。。
先日(2014年秋)、AutoScaling でインスタンスのステータスが取得できるようになったので、OpsWorks で AutoScaling が使えるようになるのも近いかもしれません。
EIP(固定IP) を間違って消してしまうことがある
うろ覚えなのですが、EC2 だとインスタンスを terminate しても EIP は消えなかった気がしますが… OpsWorks ではインスタンスを消すと、EIP ごと消えてしまいます。EIP を利用しているインスタンスかどうかは一目で分かりますが、OpsWorks ではそのサービスの性質から、インスタンスを消すことが多いため、誤って EIP を消さないように注意する必要があります。
(OpsWorks で EIP を利用するためには、OpsWorks のリソースに EIP を追加する必要があります。そのため、インスタンスを消しても EIP が残る方が自然だと思うのですが…)
スタックを跨いだ一括デプロイはできない
自前で Chef や Ansible を運用していれば、スタック(VPC)をまたいだ一括デプロイも難しくないと思います。OpsWorks は管理画面上ではこのような機能はありませんが、AWS の API を使うなりすれば実現できるかと思います。
結論:運用しながら拡張していくシステムにはぴったり
AWS で同等のサービスといえば、CloudFormation があります。CloudFormation はクラスタ内のインスタンスやネットワーク情報・リソース情報を管理するサービスです。管理された情報をもとに、既存のクラスタの更新を行ったり、同等のクラスタを新しく立ち上げたりすることが可能です。
しかし CloudFormation は JSON オブジェクトを API で管理せねばならず、中小規模で AWS を利用したい場合には大掛かりです。また、インスタンス起動時の cloud-init(現 user-data)の挙動と密接に関わるため、インスタンスの挙動を正確に把握する必要があります。
特に更新処理については失敗することも多く、更にはロールバックにも失敗してしまうとユーザー側ではもはやどうすることもできず、AWS に問い合わせなければなりません。1ヶ月ほど利用しましたが、あまり頻繁にクラスタの更新を行うような想定はされていないような雰囲気でした。逆にカッチリとクラスタ構成が決まっているような、例えば AWS 上でクライアントごとにクラスタを立ち上げて提供するようなサービス形態の場合にはピッタリです。
一方 OpsWorks の利点は、その気軽さにあります。user-data で行うことはイベントの概念に包み隠され、ユーザーは "Setup" "Configure" などの5つのイベントのみを意識すれば十分で、それもレシピを通じて設定できるので簡単です。インスタンスを増やしたり減らしたりするのも、AWS の管理画面から行えるので、試行錯誤しながら徐々にサービス拡大していくような使い方の場合には非常に適していると思います。
OpsWorks は VPC やセキュリティグループなど、基本的な部分は全て自前で用意する必要があります。RDS さえも自分で作って、それを OpsWorks に追加する流れになります。ここだけ CloudFormation を利用するような使い方もでき、実際にそのように運用しているかたもいるようです。対象となるサービスの形態を考えて、うまく組み合わせて利用してみてください。