インフラチームと開発チームの垣根をなくすためにAWSのCI環境を構築した話

こんにちは、VOYAGE GROUP システム本部の @s-tajima です。

PHPカンファレンス2016 の「老舗メディアが改善に取り組んでいる話」でもお話した通り、長年オンプレミス環境で稼働してきたECナビを、AWSに移転しようというプロジェクトが進行しています。

そしてなんと先日、約24時間のメンテナンスを経てECナビの本体(Webサーバ, 管理画面サーバの一部, データベースサーバ)がAWSに移転しました!

AWS移転において得た知見, 構築したシステム等は数多くありますが、今回はCloudFormationとTravis CIを用いて 生産的安全手軽 なAWSのCI環境を構築したお話です。

背景

ECナビは、500万人を超える会員を抱えたVOYAGE GROUPが運営している中でも特に大きなメディアの1つです。
今回、そんなECナビのインフラ調達期間の削減、検証環境構築の簡易化、レガシー環境からの効率的な脱却等、ユーザーさんに価値を届けるスピードを加速させるための施策の1つとしてAWSに移転することを決めました。

17年もの長い期間オンプレミスで稼働してきたシステムのため移転に必要な作業は数多くあり、その中の一作業であるAWS環境の構築 だけに それほど大きな手間を掛けるわけにはきません。

このような背景を考慮して、ECナビのAWS環境の構築は

  • ユーザーさんに価値を届けるスピードを加速させるという目的を阻害しない 生産的 な環境
  • 多くのユーザーさんを抱えるメディアとしてそれに見合った 安全 な環境
  • 大きな手間をかけず 手軽 に実現できる環境

を目指して進めようと考えました。

生産的な環境 とは

オンプレミス環境での運用時、よく見られた光景が

  • ECナビ開発チーム「新しいサーバー使いたいわ。インフラチームさん用意してー。」
  • インフラチーム「はいはい。でもちょっと忙しいから来週まで待ってね。」
  • ECナビ開発チーム「(う、サーバーがもらえないと先にすすめない。。)」

というものです。 ECナビ開発チームのメンバーからすると、 自分でコントロールのできない待ち時間となり、時間のロスが発生してしまっています。

このようなやり取りは、弊社以外でも多く見れるかと思います。
オンプレミス環境で運用していると、データセンターの運用や物理機器の調達等を特定のチームで担当したほうが効率がよい場面が多く、自然とこのような分業が進んでしまうのかと思います。

AWSに移転した後、さきほどのやりとりが

  • ECナビ開発チーム「新しいEC2インスタンス使いたいわ。インフラチームさん用意してー。」
  • インフラチーム「はいはい。でもちょっと忙しいから来週まで待ってね。」

となってしまうとオンプレミス時代のような時間のロスがそのまま残ってしまいます。
本来はECナビ開発チームのメンバーが新しいサーバーを使いたくなった時には、待ち時間なく自ら環境を作成できるようになるとよさそうです。

今回はこのような時間のロスをせずに済む生産的な環境を目指しました。

安全な環境 とは

では、前述のような生産的な環境を実現するために、単純にメンバーみんなに権限だけ渡して
各自の好きなようにAWSリソースの操作をしてもらうようにして終わりでよいでしょうか?

もちろんこのようなやり方でうまくいく場合もあるかと思いますが、 そのような環境では、

  • オペレーションミスによって本番用のEC2を誤ってターミネートしてしまった。
  • いつの間にか本番用のRDSがインターネットのどこからでもアクセスできるように設定されてしまっていた。
  • 設定した経緯がわからず、不要だと判断し削除したSecurityGroupの接続許可設定が、
    実は使われている頻度は少ないがとても重要なものだった。

といった事故が起きてしまう心配が残ります。

ここまで極端な例はなかなか起きないとしても、 多くの人が好き勝手にAWSリソースを操作でき、その変更内容の管理ができていないような環境では多くのユーザーさんを抱えるメディアとしてそれに見合った安全な環境を提供できてるとは言えないと考えました。

理想としては、

  • AWSリソースの操作はレビューを通してから行う
  • AWSリソースの操作があったタイミングで通知を行う
  • AWSリソースの操作の内容は記録に残し、後から履歴や経緯を追える

ということができるような安全な環境を目指しました。

手軽に実現できる環境 とは

ここまでの要件を満たせるような環境は、サーバーを用意し、便利なツールを導入し、さらに必要であれば自らコードを書くことで(つまり時間さえかければ)いくらでも実現できるでしょう。

しかし、自前でこのような環境を用意しようとすると権限管理、バックアップ、冗長化、監視等、障害時の対応等、本当に必要だった要件に加えて考えなければいけないことが次から次へと出てきます。

このあたりを可能な限りマネージドサービスにまかせてしまうことで、手軽に環境が用意できることを目指しました。

実現方法

ここまでの要件を満たすために、今回はこのような環境を構築しました。

f:id:s_tajima:20170217133520p:plain

この構成では以下のような流れでAWSリソースを操作します。

  1. GitHubで管理されたCloudFormationのテンプレートを修正し、Pull Requestを作成 (作業者)
  2. Pull Requestの作成/更新をフックにビルドを実行 (Travis CI)
    • 2.1 ValidateTemplateを実行
    • 2.2 CreateChangeSetを実行
  3. Pull Requestの内容とChangeSetの内容をレビュー (レビュアー)
    • 問題がなければLGTM
    • 問題があれば指摘して2からやり直してもらう
  4. ExecuteChangeSetを実行 (作業者)
    • 4.1 CloudFormationがAWSリソースを操作
  5. AWSリソースの変更結果を通知 (CloudFormation -> Lambda -> Slack)
  6. 変更の結果を確認 (作業者 or/and レビュアー)
    • 問題がなければ次に進む
    • 問題があれば2からやり直し
  7. Pull Requestをマージ (作業者)

いくつかのポイントを説明します。

まず1つ目のポイントは、AWSリソースの操作にCloudFormationを使い、そのテンプレートをGitHubのリポジトリで管理している点です。 このリポジトリには、弊社のメンバーであれば誰でもPull Requestを送ることができます。 そのため、必要だと思ったメンバーが自らテンプレートを書き、それを適用することですぐに必要なリソースを構築することができるようになっています。

変更作業の前にPull RequestやChangeSetのレビューを受けることで、意図しない変更や経緯のわからない変更がされてしまうことを防ぎます。

ChangeSet(変更セット)についてはこちらに詳しく記載してあります。
https://aws.amazon.com/jp/blogs/news/new-change-sets-for-aws-cloudformation/

また、CloudFormation操作の通知はSlackに飛ばされるようになっていて、もちろんCloudTrailもAWS Configも有効にしてあります。
このように、 生産的安全 な環境を実現しました。

2つめのポイントは、Travis CIを利用している点についてです。 これは言うまでもなく 手軽 にCIの環境を手に入れるための手段です。 しかしそれだけではなく、Travis CIを 安全 に利用するための工夫をしています。

Travis CIに登録してあるIAMユーザーの権限は、 ValidateTemplate, CreateChangeSet に限定しています。
そのため、もし仮にTravis CIからIAMのクレデンシャル情報が漏れてしまっても、その情報だけでは ExecuteChangeSet を実行できないためAWSリソースを自由に操作することはできません。

また、テンプレートを編集できるメンバーは ExecuteChangeSet と必要なリソースの参照の権限しか持ちません。
CreateChangeSet の実行をTravis CIからのみに絞ることで、本CIフローから外れたAWSリソースの操作が行われてしまうのを防いでいます。

まとめ

以上、CloudFormationとTravis CIを用いた 生産的安全手軽 なAWSのCI環境の構築のお話でした。

冒頭の自己紹介の通り、僕はシステム本部所属のインフラチームのメンバーなのですが、PHPカンファレンスの資料にあるような交換留学の一環で現在はECナビの開発チームのメンバーと共にECナビの環境改善に全力を注いでいます。
今回の話もインフラチームと開発チームの垣根をなくすためのとてもよい施策になったと思っています。

お知らせ

現在、(ECナビを含む)メディア領域、システム本部ではそれぞれ一緒に働く仲間を募集しています。

どちらのチームにも、まだまだ解決したい課題がたくさんあります。
ご興味のある方はぜひお気軽にご連絡ください。