AWSアカウント分割のススメ:セキュリティと運用効率が改善したよ


もうすぐジョインして1年になるSREの徳原です。今日はジョインして最初の大きめプロジェクトの1つであるAWSアカウントを分割した話をつらつらと書いていきたいと思います。

これからプロダクトのインフラをいい感じにしていくぞ!!!と考えている同志の役に少しでも役に立てればと。

どのスタートアップでも言えるでしょうが、最初からインフラを綺麗に作るということは、人的リソースや、プロダクトのフェーズからして難しく、必要最低限のインフラ環境だけ整えて、あとはアプリ機能を爆速で開発し、ユーザに価値を届け、そのまま突き進んでいく方向に舵を切っているかと思います。そしてプロダクトがある程度形になり、安定性や、信頼性が求められ始めたところでやっとインフラ側なんとかしないとね、というのがよくある話かなと。

忙しい人向けサマリ

  • AWS設計で困ったらベストプラクティスに乗っておく
  • AWSアカウント分割を進めるにあたり、作業内容自体は難しくないが、関係者が多くコミュニケーションをしっかり取ること
  • AWSアカウント分割で権限設計の幅が広がり、運用が楽に

AWSアカウント分割にむけて


※ 常にクラウドサービスは更新されているので、読者自身が作業する際は、最新の仕様を確認することを推奨します。

入社した当初のestieのインフラ構成とその課題感

自分が入社した当初、プロダクトが動いているAWSアカウントは1つでした。そのAWSアカウント上に、さまざまなプロダクトのProduction, Staging, Development環境がそれぞれ動いていました。プロダクトによって、この3環境が存在していたり、StagingかDevelopmentどちらか存在しない2環境になっているといった様々な状況でした。
一部プロダクトを除き、VPCは各環境各プロダクトで分かれており、Terraformでの運用もされており、しっかりインフラが整備されていると印象を受けたのをよく覚えています。
また、AWSアカウントとしては、前述のアカウントの他に、Sandbox用、Log用(アカウント発行して機能してない)の合計3アカウントが存在し、1つのAWS Organization(以後 旧Org)になっていました。

ただ、開発者に割り当てるIAM Userの権限管理が複雑化しており、その影響で不要な権限が付与されているといったシステム運用、セキュリティ的にはあまり喜ばしくない状況も発生していました。これを是正しないことで将来的に何かしらの事故に繋がるという事例もあり、未然にそれを防ぎ、プロダクトに注力できる状況を作り出す必要がありました。

そうした背景から、AWSアカウントを適切に分割し、権限周りを適正化していくというAWSアカウント分割のプロジェクトをスタートしました。

AWSアカウント分割の方針決め

前述した通り、すでに旧Orgが存在していたのですが、 管理アカウント = プロダクトが動いているアカウント であり、管理アカウントに開発者がアクセスしている状況になっていました。

管理アカウントのベストプラクティス - AWS Organizations

にあるように、管理アカウントにはアクセスできるユーザを制限するというベストプラクティスがあり、個人的には管理アカウントは基本的にログインせず、ログインがあれば即座に通知するといったレベルのセキュリティを保っておきたいです。

ただ、残念なことに、現状AWS Organizationの管理アカウントの変更は不可能なので、新しくAWS Organizationを作り直すしかありません。AWSアカウント分割プロジェクトはOrganizationの新規作成からスタートしました。(以後 新Org)

困ったらプラクティスに乗っておけ! AWS Organization設計

10年弱程度AWSを使ってきてますが、AWS Organizationをどっぷり運用したことはありません。ましてや一から設計したことはタイミング的にこれまでなかったので、とりあえず文献を漁るところから始めました。

基本的には公式ドキュメント、公式ブログを重点的に読み、参考がてら他社テックブログを読みます。

進めるにあたり、新Orgの管理アカウントはさっさと払い出しておき、ドキュメントと実際のコンソール画面を突き合わせながら、AWS Organizationを作成したら必要最低限設定しておくべきもの、後から考えることができるものに分けて着手していきます。

最初にしておくことの例としては以下のような感じでしょうか。

  • invoice周りの設定
    • お金は大事だよ〜
    • 経理とフローを握っておこう
  • セキュリティ用、監査ログ保管用、IAM Identity Center用といった委任先AWSアカウントの作成
    • 管理アカウントではリソースを基本的に動かさず、別アカウントに委任できるものは委任する。
  • アカウント発行時のCloudFront, AWS Config, GuardDuty, Security Hubの自動設定
    • Control Tower使ってもいいかも
    • 今回は私はControl Towerを使わないという選択をとっています。当時はまだ連携されてないサービスがあったり、管理上のネガティブになりそうな情報があったため、今後の要件変更などに備え一旦全部実装する方向に舵をきりました
  • IAM Identity CenterでSSOログイン設定
  • Health Dashboardで全アカウントのメンテナンス情報の集約設定

逆にOUや、サービスコントロールポリシーなどは後からでもできる(後から設定するのは、それはそれで怖いですが)ので後回しにしてます。
基本的にAWSのリソースを設計する際、経験が足りず設計に困る際は、AWSが出しているプラクティスに乗るのがプラクティスです。

地味にやることがある既存AWSアカウントの移管

新Orgの整備の目処がついたら、次は旧OrgにあるAWSアカウントを移管します。

移管にあたり、旧Orgに所属するAWSアカウントは一度スタンドアロンに変更し、その後新Orgに所属させる必要があります。
現時点では新Orgに直接付け替えることはサービスの仕様として不可能です。

スタンドアロン化の注意点としては、AWS Organizationから作成したAWSアカウントは、支払い設定がないのでその設定を行い、また、phone pin verificationを実施する必要があります。
超重要: 作業を進める前に、電話番号等、連絡先が最新化されているか必ずチェックをしてください!
電話番号は代表番号等になっていると思うので、前もって社内の担当者に相談しスムーズに連携できる準備をお忘れなく。

メンバーアカウントから組織を退会する - AWS Organizations
AWS Organizations のメンバーアカウントを他の組織へ移行する: Part 1 | Amazon Web Services ブログ

ちなみにAWS費用はそれまで所属していたところに請求されることになります。旧Org → スタンドアロン → 新Orgと遷移するため、それぞれの状態で発生した費用はそれぞれのbilling設定に紐づくことになります。一時的にAWSから異なった金額で複数請求が来ることになります。経理担当の方とは事前に調整をしておきましょう。

旧Orgから管理アカウント以外がいなくなればAWS Organizationを削除し、新Orgに所属すれば本作業は完了です。
ちなみに、AWS Organizationは完全閉鎖されるAWSアカウントが残っている場合削除できません。AWSアカウントを閉鎖してから90日経過したら完全閉鎖になります。そのため、もしあなたが私と同様にAWS Organizationの移行を決めた場合は早めに不要アカウントをクローズすることをお勧めします。私は直前でこの仕様に気がついたので、閉鎖したAWSアカウントを一旦再開させ、移行後にクローズするという二度手間をとりました。。。

Close an AWS account - AWS Account Management

幕間: 各プロダクトとのSREチームの関わり

estieでは各プロダクトのインフラ管理にTerraformを使っているのは先でも少し触れました。これまでの運用の中で、今後を楽にするために、改善した方が良い点がありこのタイミングで対応してます。

一言で言うと、プロダクト横断で設定した方が良いものはSREチームが責任をもって行う、です。

estieではインフラやアプリケーションのデプロイ方式がほぼ統一できており、GitHub Actionsで利用するOIDC用のIAM Roleを各プロダクトのTerraformで設定するよりSREチームで一元管理した方が効率的です。この他にも、AWSメンテナンス情報や、アプリケーションコンテナの異常終了や、起動失敗情報を取りまとめて通知するといった機能もSREチームの責任範囲としています。

概略図

Staging/Development環境を別AWSアカウントへ移行する

ここからが本プロジェクトのメインどころです。
今プロダクトが動いているアカウントをProduction環境専用とし、Staging, Development環境を新しいAWSアカウントに移行していきます。

フローとしては大雑把に書くと以下となります。

  1. データ移行方針について各プロダクトチームと認識合わせ
  2. S3, RDS, ElasticCache, EC2などデータを持つもの以外を新しいアカウントに作成する
  3. データ移行
  4. デプロイフローを新しいアカウントで実行されるように変更

1. データ移行方針について各プロダクトチームと認識合わせ

プロダクトチームと話に行く前に、まずは移行対象のプロダクトの全体構成を必ず把握することが重要です。

estieでは、基本的にECSでアプリケーションを稼働しており、ecspresso, ecscheduleでそのデプロイを行なっております。プロダクトによってはLambda Functionsも利用しており、Serverless Frameworkでデプロイしていたりと、様々な状況です。全てがTerraformで管理されていれば、Tagが基本的にはついているので、対象の洗い出しもResource Managerを使えば簡単に行えますが、そうもいきません。

仕方がないので、Billing Dashboardから使われてるサービスを洗い出し、各リソースの管理画面にアクセスし、移行対象プロダクトの名前や、ものによっては設定内容まで全て確認するという泥臭い方法で洗い出していきます。

そうして、プロダクトの構成を把握し、その内容の確認から、データ移行対象を明確化し、移行作業の内容を決めていきます。キャッシュ系は基本的に移行不要にできる可能性が高いため、必ず確認してください。また、S3はAWSアカウントを跨いでも同じ名前でバケットを作成できないため、そこの要件確認も必須です。

また作業時間もここでフィックスさせておきましょう。Productionの移行だと基本的にサービス断は避けながら行うものですが、Staging/Development環境の移行の場合は、内部調整だけで、サービスを止めて移行することが容易なので、可能な限りサービスを止めて実施しましょう。

私は開発に影響が出ないし、自分の気も楽なので夜間の時間帯に一人黙々と作業をしてました。

2. データ移行対象外のものを先に作成する

Terraformでインフラをすでに管理済みなので、terraform applyに使用するIAM Role, tfstate保管用のバケットや、一部パラメータを変更するだけで基本的に移行が完了します。
Route53のZoneだけはNS委任するなりして対応しないといけないので必要に応じてNS委任する等の対応が必要です。

もしドメインの変更が可能であれば、新規ドメインの取得も視野に入れて動くと良いかもしれません。ドメインを変更する場合は、アプリケーション側でHostを指定していて起動しているものがないか等確認することを忘れずに。

3. データ移行

それぞれのリソースごとに移行方法があるので、状況に応じて、適した移行方法を選択してください。
基本的にはAWSの機能でSnapshotや、AMIを別アカウントにシェアする機能があるため、それをベースに考えると良いかと思います。

一部ハマりポイントになりそうなところを紹介させてもらいます。

RDS

ディスク暗号化をしており、且つその暗号化キーをAWS Managedのものにしている場合、Snapshotの共有ができません。 解決策としては、前もってCustomer Managedのキーを作成しておき、このキーをStaging/Development側のIAMからもアクセスできるようにしておきます。そして、取得したSnapshotをこのキーで再度暗号化してやれば、共有ができるようになります。 DB クラスターのスナップショットの共有 - Amazon Aurora

S3

同じ名前でS3 Bucketは作れないという仕様があります。そのため、Bucket名をそのまま使いたい場合、一度別のS3バケットを作成し、そこに既存オブジェクトをCopyしてやる必要があります。そして、S3 Bucketを一度消して、同じ名前で新しいアカウント側で作るというオペレーションが必要となります。

移行にあたりS3 Batch Operation Amazon S3 バッチオペレーション – AWSのCopyを利用すると良いです。
Copyに必要なmanifestファイルの作成は一例ですが、以下のコマンドで作成できます。(versioning対応)

aws s3api list-object-versions --bucket <対象バケット名> \
| jq -r '.Versions[] | ["<対象バケット名>",.Key,.VersionId] | @csv' \
> manifest.csv

数十のバケットを移行しましたが、大体一度消してから、新しいアカウントで作り直すまで1時間くらい待つ必要があります。タイムアウトを長くして、terraform applyを流しておくと、1時間後くらいに作られてるので、その方法が手間がなくおすすめです。

4. デプロイフローを新しいアカウントで実行されるように変更

2.で行なったTerraformと近い作業となります。GitHub Actionsで使用するIAM Roleを変更し、ImageをプッシュするECRのURL、ecspresso/ecsheduleにて、tfstateファイルからパラメータを読み込む場合はS3バケットおよびpathを新しい環境に切り替えて実行すれば完了です。

--

このように書くと簡単そうに見えますが、細かく手順として書くとなかなかなボリュームになります。また、作業中にもプロダクト開発は進むので、やるなら注力して一気にやることをおすすめします。

幕間: Network構成をTransit Gatewayに移行

ちょうど本作業を進めている際に以下のEIP課金について発表がありました。estieでは各プロダクトのVPCごとにNAT Gatewayを使っていましたので、EIP課金が始まることで結構なコスト影響があります。また、NAT GW自体のコストも嵩んでいたため、このタイミングで、Transit GWへ切り替え、NAT GWを共通化するということも取り組みました。(SREの別メンバーが主体。ありがとうございます!)

Transit Gateway Attachmentもそこそこの金額がかかりますが、冗長化したNAT GWよりかはコストが安くトータルで見るとコストも下がり、ネットワーク的にも今後はVPC Peeringを使わなくて良くなったので、かなりシンプルなネットワーク構成にすることができました。
新着情報 – パブリック IPv4 アドレスの利用に対する新しい料金体系を発表 / Amazon VPC IP Address Manager が Public IP Insights の提供を開始 | Amazon Web Services ブログ
estieはtoBでのSaaSサービスを展開しているので、NAT GWのポートが枯渇するといったことがそもそも起きにくいサービスになるので取れた構成になります。

まとめ

作業量は多いですが、ドキュメントがネット上に充実しており一つ一つの作業は難しいものではありません。しかし、関係者が多くいるため、きちんと広報することや、コミュニケーションを密に取ることはとても重要なのでしっかりやっていきましょう。

本対応の結果として、権限管理がとてもシンプルになり、運用面がかなり楽になりました。セキュリティレベルに応じてリソースを別AWSアカウントに切り出し、アカウント単位でそもそもアクセスさせないといった選択肢もとれ、設計の幅が広がりました。

最後に

最後までお付き合いいただきありがとうございます。テックな記事を書こうと思いつつ筆を取ったら見事に文字だらけになりました。次の記事はもう少しテッキーな記事を書きますので、ご期待ください。

まだまだestieのSRE領域はこれからと言う段階になります。これからSREを形作っていきたいと言う方には本当にちょうどいいタイミングだと思います。少しでも興味がありましたら、まずはカジュアル面談を申し込んでみましょう。

雑談したいぜ!

hrmos.co

© 2019- estie, inc.