1. インフラ
エクメルンで実際に参考にした書籍・サイトや設計、利用ツールや各コンポーネントで気をつけたことなどを挙げます。
1.1. 参考書籍・サイト
- 書籍
- 「Amazon Web Services クラウドデザインパターン設計ガイド」 玉川 憲氏 他 デザインパターンが網羅された本。「これは使えそうだな」とワクワクしながら読めるので非常に楽しく、かつ実践的。
- 「Amazon Web Services実践入門」 舘岡 守氏 他 ハンズオン形式で学べるので、まずは雰囲気をつかみたい人にはちょうどよいと思います。
サイト
AWS ドキュメント (公式ドキュメント)
利用しようとするコンポーネントについての情報は前もってざっと目を通したほうがよいです。重要な情報やベストプラクティスがさらっと書かれていたりします。ちょっとわかりにくいな、というところは英語の方を読むとすんなりわかったりします。AWS クラウドサービス活用資料集 (公式オンラインセミナー資料)
無料のオンラインセミナーの資料が無料で公開されています。非常に有益な情報が詰まっています。こちらも利用しようとするコンポーネントについての情報は前もって目を通しておいた方がよいです。Amazon Web Services ブログ (公式ブログ)
常に目を通して置きたいところです。Developers.IO
クラスメソッド社のブログ。実践的で非常に参考になります。The Twelve-Factor App
Herokuが提唱するモダンなWebサービスを作るための方法論です。
1.2. 設計
- 本番環境とステージング環境はAWSを別アカウントに
- インスタンス起動時にUserDataで環境差分を動的に変えるコンフィギュレーション済みのカスタムAMIを用意し、本番環境とステージング環境で共通利用
- WebアクセスはCloudFront → ALB → EC2な流れ
- EC2はASGでスケールアウト
- 全部HA構成
- バッチ処理やWebアクセスの非同期処理、外部クラウドサービスとのAPI通信はSQS → ワーカー (EC2)な流れ
- CI/CDはCircleCI、GitHub、CodeDeploy
1.3. 利用ツール
- Packer
カスタムAMI作成で利用します。Packerが作成するSSHキーが気になったのでprovisionersの最後で削除しました。 - Ansible
PackerからAnsibleを呼び出して利用します。稼働中のインスタンスにも変更を加えられるようにべき等性を守るようにコーディングしましたが、割り切ってべき等性は切り捨ててもいいような気がしました。 - Terraform
コンポーネントのオーケストレーションに利用します。非常に使いやすいです。やむを得ない理由で手作業した後でも救済措置があるのがなにげにうれしい。 - Apex
Lambdaビルド & デプロイで利用します。
1.4. コンポーネント
- VPC
- Multi-AZ、機能毎の分割を考慮し、サブネットをきれいに分割します。
- EC2
- タグは必ず付けた方がいいです。→ 将来何か処理を追加したりするときに役に立つことがあるやも。
- 利用しないのであればAmazon Linuxがデフォルトでポートオープンするサービス(rpcbindとnfslock)をUserDataで停止します。
- UserDataのメイン処理はS3に配置し、UserDataではそのメイン処理を取得し実行するだけにします。→ UserData修正の都度、カスタムAMIを作り直す作業が面倒であったため
- 外部連携でIP制限をかけているEIPはTerrafromでprevent_destroyしておきます。→ 誤って削除してしまうのを防ぐため
- AmazonLinuxのパッケージアップデートを停止し、ロケールとタイムゾーンを変更します。→ 動作保証の観点から
- CodeDeploy
- AutoScaling+CodeDeployで自動作成されるインスタンスでは、CodeDeployエージェントは予めAMIにインストールしておくのではなく起動時にUserDataでインストールするようにします。→ (恐らく) インスタンス起動時にCodeDeployエージェントのアップデートが走りCodeDeployのDeployとコンフリクトしエラーとなるため
- 上記に加え、UserDataでEIPをセットする場合は確実にEIPがセットされたことを確認してからCodeDeployエージェントをインストールするようにします。→ (恐らく) EIPが完全にセットされずにdeployが始まりエラーとなるため
- ALB
- SSL証明書が必要な場合はALBを利用し、ACMでSSL証明書を集中管理します。→ SSL証明書をコード管理したくないため
- RDS
- PostgreSQLはデータベース作成時に照合順序とCtypeを設定します。→ パラメータグループでは変更できず、DB作成後に変更する場合はDBを作り直す必要あり
- 各種イベント (特にメンテナンス) をSNSで通知を受けるように設定します。
- DynamoDB
- コスト削減のため、key名とvalueはコードの読みやすさのバランスを取りつつ、できるだけ短くします。
- SNS
- システムのアラート通知で利用するトピックにはエンドポイントを複数登録し冗長化します。→ エクメルンではSlackとメールの2系統
- メール内のunsubscribeリンクを無効化します。→ 誤って操作しないように
- S3
- アプリのログなどを置くログバケットを作成し (CloudTrailのバケットではないです) 、会社のポリシーにあわせてライフサイクルを設定します。
- 外部非公開とするバケットは公開されないか監視します。
- ログバケットは限られた監査用IAMロールからしか参照できないよう設定します。
- Kinesis Firehose
- 各サーバのログをFluentdを用いてFirehoseに投げて、サーバレスでS3にデータを保存します。
- 保存するデータをAmazon Athenaで分析しやすい形式に変換しています。
- CloudWatch Logs
- アプリケーションログを閲覧するために利用します。
- ログをJSON形式で出力すると、各フィールドを検索条件に利用できるので便利です。 例: status_code != 200
- CloudTrail
- 保守や監査で必要なので有効化します。
- Route53
- 内部通信にはRoute53のプライベートホストゾーンを利用します。→ 障害なでエンドポイントを切り替えたい場合にRoute53の設定を変更するだけで対応できるため
- CloudFront
- 必ずWAFを設定します。→ DDoS防御と悪質なアクセスのブロック用に
- WAF & Shield
- セキュリティオートメーション を検討します。
- IAM
- 必ずAWSアカウントに別名をつけます。→ アカウントを取り違えて操作ミスを防止するため
1.5. 節約のポイント
- Trusted Advisorで定期的に見直しをします。
- リザーブドインスタンスを検討します。→ オンデマンドで運用を続けた場合とリザーブドインスタンスを適用した場合の損益分岐点を考えると判断がつきやすいと思います。またEC2は将来スケールアップする可能性がありそうならコンバーチブルリザーブドインスタンスが非常にオススメです。
1.6. 作っておくと便利なスクリプト
- すべてのインスタンスで起動しているアプリケーションを一括で起動・停止できるスクリプト→ DBマイグレーションを必要とするようなリリース時に便利です。
- すべてのインスタンスに対して複数のアプリケーション・デプロイメントグループを一括でCodeDeployできるスクリプト→ 同上
- EC2インスタンスを一覧表示するスクリプト→ タグ名、IPアドレス、インスタンスID、起動時間を表示するスクリプトで、軽く全体のインスタンスの情報を取得したい場合に便利です。
- Tabキーで補完可能なタグ名でSSHができるようにするスクリプト→ 踏み台サーバーから別のサーバーにSSHしたい時にタグ名でSSHできるようにします。タグ名はTab補完可。→ エクメルンではサーバー数が多くないので大変使い勝手がよいです。
CoffeeBreak
エクメルンでInfrastructure as Code (Ansible) の思わぬ恩恵を受けました。
- 構築スピードアップ 自社他サービスのAnsibleコードの横展開利用で構築がぐんと楽になりました。
- ジョブチェンジの足がかり インフラ本職の人たちのナレッジがコードで見える化しているので、インフラ未経験なデベロッパーへのスキルトランスファーに役立つと感じました。