TechBlogSideCIのエンジニアによる技術ブログです。Otherはじめまして。4月にアクトキャットにjoinしたwata727です。サーバサイドの開発やAWSをはじめとしたインフラ周りを担当しています。今回は直近行ったSideCIインフラのAWS完全移行に、TerraformやPackerを採用した話について書いてみます。SideCIのインフラ構成SideCIではサーバの役割をフロント側でユーザの操作やリクエストを受け付けるweb群と、Rubocopなどのツールを実行するnode群に分けています。役割を分離することにより、関心事を分けることができ、必要に応じてスケールアウトやスケールアップがしやすくなるメリットがあります。AWSとGCPのハイブリットクラウド構成をとっていたのですが、さまざまな問題があり、今回の再構築の段階でAWS側に完全に寄せる形になりました。弊社には専属のインフラエンジニアがいないため、サーバサイドエンジニアでもある程度分かりやすく扱えるようにし、かつインフラ側のコードも全てGitHubで管理を行うようにしました。これによりコードレビューと履歴化ができるようになります。過去のインフラ変更やパラメータチューニングの履歴を残すことで、変更の意図を伝えることができ、レビューによって他のエンジニアの現状に対する理解、インフラそのものに対する理解を深める教育的な側面も期待できます。Terraformの採用AWSのオーケストレーションツールにはTerraformを採用しました。Formationなどがありましたが、当時はDryRunに対応していない、JSON書きたくないなどの理由から採用を見送っています。最近はDryRunにも対応したようですね。Terraformでは、インフラの構成をコード管理することはもちろん、手間のかかるインフラの変更作業などを自動化することができます。新しいインスタンスにセキュリティグループを割り当て以前のインスタンスに紐付いていたEIPを割り当てELB配下にアタッチ...というような手順が必要になります。applyすると上記の手順を自動で行ってくれます。これはTerraformで各リソースの対応関係を設定しているために実現できます。具体的には、以下のようなリソースの定義で、対応関係を記述できます。true}${aws_instance.web.id}のように書くことで、特定のインスタンスではなく、Terraformで設定中の名前のリソースが指定されるため、再作成されてインスタンスIDが変更されても、関係を維持するようにTerraformがAPIを叩きます。AMIを変更する場合には変数として分離したweb_ami_idの値を変更することですべての変更が完了します。planで実行計画の内容を確認します。destroy.このように、該当の変更によって、Terraformがインスタンスの削除、新規作成、EIPのアタッチ、ELB配下へのアタッチを実行することがわかります。作業の実行順序などもエラーが生じないように適切に処理されます。Terraformで可能な限り、各リソースの対応関係を記述することで、手間のかかる手順を自動化することができ、人的ミスを軽減することができます。Terraformはステートファイルという仕組みを使用してリソースの状態管理をしています。そのままではすでに作成されてしまっているリソースは管理下に置けないのですが、Terraformingという有志が作られたステートファイルやテンプレートを既存のリソースから生成するgemがありますので、これを使ってテンプレートに落とし込みます。これで現状のAWS上のリソースをコードに落とし込み、可視化することができました。Packerの採用また、別の問題として既存のサーバの構成管理がされていないという問題がありましたので、同時に構成管理ツールとしてのPackerを採用しました。Packerを構成管理ツール、というと少し違和感があるかもしれませんが、サーバのプロビジョニングをコードに落とし込んで管理できることから、ここでは構成管理ツールとして扱っていきます。他候補としては、ChefやItamae、Ansibleなどありましたが、最終的にはシンプルであることと、AutoScaling対応を見越してAMIを作ることに注視することなどが採用の決め手となりました。]}上記のようなテンプレートを作成することで、プロビジョニングを自動化できます。各種変数を外部から与える形式を取ることで、環境別のプロビジョニングを行うこともできます。web.jsonPackerはChefやAnsibleをプロビジョナーとして採用することもできますが、今回は安直にシェルスクリプトを使用しています。現状、そこまで複雑でないので、秘伝のタレ化はしていませんが、バッドプラクティス気味でもありますので、将来的には別のプロビジョナーに切り替えるかもしれません。サービスインを担保するための検証にはServerSpecを採用しています。テストに落ちるとAMIがビルドされないので、ビルドされているAMIはすべてテストに通過しているという安心感があります。Infrastructureのゴールデンイメージ問題と同じですが、現状、Packerのビルドを走らせて、AMIを取得するまでに約30分程度かかります。仮に、常に新しいアプリケーションのコードを内包するとなると、デプロイのたびに毎回30分以上のタイムロスが発生してしまい、開発効率やリリース頻度の低下が懸念されます。速度を重視するスタートアップでは致命的です。ServerSpecのテストはビルドの最後に走るので、最後の最後に要件を満たせてなくてAMIがビルドできず、また30分待つ、という状況が発生することがあります。現状は、アプリケーションのデプロイは従来通りCapistranoを使い、何か新しいものをインストールしないといけないような場合だけPackerでAMIをビルドし直す方針をとっています。今後はPackerのレイヤを分けて、毎回Rubyのビルドを走らせなくてもよくするなど、別の方法を模索していく予定です。Terraformが属人化する現状、Terraform周りの環境を自分のローカル環境に構築して、そこからapplyをやってきたので、他のメンバーが参加するためには自前の環境を構築したり、ステートファイルを共有しないといけない問題がありました。この辺りは現在取り組んでいる最中で、具体的にはChatOpsで解決を図ろうとしています。弊社では、Slackを活用しており、デプロイもChatOps的に自動化しているので、同様にインフラ変更もChatOpsでやっていく予定です。完全には導入しきれていない状態ですが、Packerのビルドなども常にチャット経由で行えるような環境を構築していきます。Hiring!こんな感じでSideCIを開発するアクトキャットでは、エンジニアの生産性を高めるサービスを作るために、自らの生産性向上のための取り組みも積極的に行っています。新しい技術を採用しつつ、メンバーでよりよい形を追求するために議論を重ねることができる環境です。EFSにcloneしたら遅かった話この記事で説明したGitの話には、私の誤解が含まれています。コ...2016-10-11SpotFleetを使ったらEC2のコストが1/4になった話こんにちは。最近SideCIのインフラまわりを見ている@wata727で...2016-08-18PackerのAMI手動管理を卒業するプラグインを作ってみたこんにちは、家から捕まえられるポケモンだけを捕まえて僕のポ...2016-07-05「エンジニア向けサービスを支える技術」を開催しました。