自己紹介と今回のテーマ

新津佐内氏(以下、新津):みなさん、こんにちは。株式会社カサレアルの新津佐内と言います。本日は「これやったの誰?」というタイトルのお話をします。

「これやったの誰?」についてですが、DevOpsと合わせて自動化を進めていく中で、自動化したオペレーションに対しても生じたこの疑問に、実業務の中であらためて向き合ってみました。上記事例の詳細と現時点での我々の答えを紹介します。

まず本日お話しする内容ですが、スライドに書かれているような基盤の運用担当者のユースケースに関わるお話になります。どのようなユースケースかというと、① 開発プロジェクト側からの環境構築依頼を運用担当者が受ける、② 運用当社が環境構築をインフラアズコード(IaC)で実施、③ 構築した環境をプロジェクト側に提供といった、よくあるユースケースです。

このユースケースをもとにお話ししたいテーマは下記2点です。「運用担当者がIaC(インフラアズコード)を実行するアカウントって、誰のアカウントを使用していますか?」「そのアカウントのクレデンシャル情報ってどこに保存していますか? 」。どちらも運用担当者であれば気になるテーマではないでしょうか。本日はこのあたりのお話を、弊社の実業務で起きた事例をもとにお話ししたいと思います。

結論から言うと、本日のお話は全体をとおしてAWSにロックインした内容となっています。AWSを使用していない方、ごめんなさい。

次に出てくるキーワードとしては「AssumeRole」。これを使用してアカウントの切り替えを行います。その次に出てくるキーワードとしては「PassRole」。これを使用してIaCの実行EC2インスタンスにロールを割り当てます。そして最後に、AssumeRoleとPassRoleを使用したことにより、クレデンシャル情報を保持する必要がなくなったね。おめでとう……というお話の流れとなっています。

AssumeRoleとPassRoleを知らない方はこのあとの話を楽しみにしていてください。AssumeRoleとPassRoleを知っている方は「ふんふん、そうだよね」と、復習のために聞いてもらえればと思います。

カサレアルの「クラウドネイティブ道場」の概要

では、私の自己紹介に代えて、弊社カサレアルの「クラウドネイティブ道場」を軽く紹介したいと思います。

弊社カサレアルでは「クラウドネイティブ道場」と称して、クラウドネイティブ技術に関するトレーニングを提供しています。スライドに記載されているコンテナや自動化などのツールをふんだんに盛り込んだトレーニング内容となっています。

「クラウドネイティブ道場」では、AWS上にて弊社が用意したアプリケーションを使って、段階的に環境を広げていく手順を実施する内容となっています。全部で7コースの構成となっていますが、1コースずつでの受講も可能です。興味のある方は、弊社ホームページ、または「カサレアル クラウドネイティブ道場」で検索してみてください。

「クラウドネイティブ道場」で提供されている環境

さて、ここからが本題です。先ほどご紹介した「クラウドネイティブ道場」ですが、受講者の方たちにはAWS上でトレーニングを受講してもらいます。そのために、受講者にはスライドに記載されている環境を提供しています。

1人の受講者につき1つのAWSアカウントと1つのIAMユーザー、各種AWSリソース(Cloud9、CodeCommit、EKSなど)を受講者ごとに用意しています。スライドの右側に書かれているような、Aさん用アカウント、Bさん用アカウント、Cさん用アカウントといったイメージの環境となります。もちろん、講師用アカウントにも同等の環境を用意します。

トレーニング開催のたびに受講者用の環境構築作業を手動でやるのはさすがに大変なので、環境構築作業を自動化して運用しています。自動化の内容としては、管理者アカウント内にIaC用のEC2インスタンスを構築。このEC2インスタンスの中にはJenkinsが入っています。

我々はこのEC2インスタンスを“Jenkinsマシン”と呼んでいます。そして、このJenkinsマシンから、各受講者用アカウントの環境にAWSの各種リソースが作成されます。

この自動化運用のポイントとなった点ですが、それは管理者のAWSアカウントと各受講者のAWSアカウントが異なる点でした。通常、異なるAWSアカウント間では、片方のアカウントからもう片方の環境にリソースを作成できません。そのため、アカウントの切り替えが必要となっています。今回の自動化運用では、アカウントの切り替え処理も考慮した設計をするように自動化担当者にお願いして、自動化の仕組みを実装してもらいました。

切り替え処理は誰がどうやって行っている?

このような自動化運用をしばらくしていたあと、ある時、弊社のマネージャーから質問という体でつっこみが入りました。

つっこみの内容はというと、「管理者用アカウントと各受講者用アカウントが異なるアカウントになっているが、管理者用アカウントから各受講者用アカウントへの切り替え処理ってどうやって実現しているのか?」といった内容でした。つまるところ、「Aさん、Bさん、Cさんの環境構築をやっているのは、誰がどのようにやっているの?」という質問でした。今回のセッションのテーマ「これやったの誰?」のきっかけとなる質問でした。

我々は自動化担当者に「自動化の中でアカウントの切り替え処理をしてください」とお願いしただけで、実際どのように切り替え処理を行っているかを確認せずにずっと運用していました。

この弊社マネージャーからのつっこみに答えるためにアカウントの切り替え処理の内容を確認したところ、意外なことがわかりました。Jenkinsマシン内に各受講者用アカウントのクレデンシャル情報が記載されているテキストファイルが存在していて、それを使用して管理者アカウントから受講者用アカウントへの切り替えをしていることがわかりました。

クレデンシャル情報はフラットなテキストで書かれていて、このファイルが流出することによって不正アクセスのリスクが高まってしまうため、現場ではこの件を境に「クレデンシャル情報を保持しないこと!」というルールが策定されました。

このルール策定に困ったのが自動化担当者で、クレデンシャル情報を保持せずにアカウントの切り替えを行う方法を検討する必要が出てきました。

検討の結果、AWSのAssumeRoleの機能を利用することにより、クレデンシャル情報を保持せずにアカウント切り替えを行えることがわかりました。

このスライドに書かれているヘルメットの絵は、AWSのIAMロールを表しています。AssumeRoleですが、「Assume」という単語は日常では「~と仮定する」という意味で使われることが多いです。ただ、ここでは「~を引き受ける」という意味合いで使われます。つまり、AssumeRoleは「IAMロールを引き受ける」という機能になります。

AssumeRoleとは

AssumeRoleをより詳しく説明します。AssumeRoleとは、AWSアカウント間でIAMロールを引き渡す方法です。Aさん用アカウントで作成したIAMロールを管理者用アカウントが引き受けると、管理者用アカウントはAさん用アカウントのAWSリソースを操作できるようになります。

このスライドの絵で言うと、Aさん用アカウントの左側にある緑色のヘルメットが、Aさん用アカウントで作成したIAMロールになります。そのIAMロールを管理者用アカウントが引き受ける、ヘルメットをかぶると、Aさん用アカウントに切り替われて、切り替わったあとはAさん用アカウントのAWSリソースを操作できるようになります。

Bさん用アカウントとCさん用アカウントについても同様に、IAMロール、赤いヘルメットや黄緑のヘルメットを作成して、それを管理者用アカウントが引き受けることにより、Bさん用アカウントやCさん用アカウントに切り替われます。

AssumeRoleの設定とIAMロールの引き受け手順

AssumeRoleの具体的な設定手順についても説明していきたいと思います。まず、管理者用アカウントに引き渡すIAMロールをAさん用アカウントで作成します。

①はAさん用アカウントでマネジメントコンソールにログイン後のIAMロール作成画面になります。信頼されたエンティティの種類に、今回は別のAWSアカウントを選択します。そしてこのロールを使用するアカウントとして、管理者用アカウントのアカウントIDを入力します。

②の画面では、管理者用アカウントがこのIAMロールを引き受けた際に実行できる、権限ポリシーを設定します。

③では、IAMロールの名前を入力してIAMロールの作成を完了させています。今回のIAMロールには「ManageEnvRole」としています。先ほどのスライドの絵の中に出てきた緑色のヘルメットが、このIAMロールになりますね。

Aさん用アカウントから引き渡すIAMロールの作成が完了したので、今度は作成されたIAMロールを管理者用アカウントで引き受ける手順を説明します。

①の画面では、管理者用アカウントでマネジメントコンソールにログインしています。ログイン後、アカウントメニューから「ロールの切り替え」を選択します。②の画面では、引き受けるロールの情報を入力します。今回は、Aさん用アカウントのアカウントIDと、引き受けるIAMロール名を入力しています。

③では引き受けが完了した状態です。管理者用アカウントでログイン中にもかかわらず、アカウントメニューに表示されるアカウント情報が「IAMロール名@アカウントID」に表示が切り替わっていることが確認できます。以降は、管理者用アカウントでログインしているのにもかかわらず、Aさん用アカウントにリソースの作成が可能になります。

スライドの下にも書いてありますが、実際の我々のJenkinsマシンでの自動化運用では、IaC(インフラアズコード)なので、このスライドに記載した画面操作の手順ではなく、CLI、コマンドにてアカウント引き受けのコマンドを実行してアカウントの切り替えを行っています。

これにて弊社マネージャーからつっこみがあった「これやったの誰?」への対応が完了しました。「Aさん・Bさん・Cさん用アカウントのリソース作成は、管理者用アカウントが受講者用アカウントにAssumeRoleして実施している。このため受講者用アカウントのクレデンシャル情報は保持していない」という改善を実現することができました。

管理者用アカウントのクレデンシャル情報は保持している?

これでめでたしめでたしとなるつもりでした。が、弊社マネージャーからまた新たなつっこみが入りました。

スライドの左側に描いてある、ピンクの指差し部分についてつっこみが入りました。「ピンク部分の環境構築を管理者用アカウントでやっているのはわかるが、管理者用アカウントのクレデンシャル情報は保持している? 保持していない?」との質問でした。

これは盲点を突かれた質問でした。Aさん用アカウントやBさん用アカウントへの切り替えであれば、切り替えのためのクレデンシャル情報の保持に気が回りますが、管理者用アカウント自身のクレデンシャル情報の保持についてはまったく意識できていませんでした。そこで管理者用アカウント自身のクレデンシャル情報を保持しているか調査したところ、またしても意外な事実がわかりました。

管理者用アカウント自身のクレデンシャル情報についても、Jenkinsマシン内の「~/.aws/credentials」ファイルに記載されていることがわかりました。このクレデンシャル情報を使用して、Jenkinsマシンは管理者用アカウントの環境にリソースを作成していたのです。これは「クレデンシャル情報を保持しないこと!」のルール違反に当たるので、すぐに改善の検討が必要になりました。

検討の結果、AWSの「PassRole」を利用することにより、クレデンシャル情報を保持せずに管理者用アカウント内にリソースの作成を行えることがわかりました。

このスライドに描かれているヘルメットの絵は、先ほどのAssumeRoleの時と同様に、AWSのIAMロールを表しています。前回のAssumeRoleと今回のPassRoleはどのように違うのでしょう? 次のページのスライドでPassRoleについて説明していきたいと思います。

PassRoleとは

PassRoleとはAWSのサービスにIAMロールを受け渡す・適用すること。ここで言っているサービスはEC2やLambda関数などを指しています。そういえば、EC2インスタンス作成のウィザードでもIAMロールの設定項目がありますよね。それがPassRoleの設定に当たります。

例えば「AmazonEC2FullAccess」ポリシーを付与したIAMロールをEC2に適用した場合、適用したEC2からCLIで同一アカウント内に別のEC2の作成が可能になります。EC2自体がIAMロール、つまり、ヘルメットをかぶり、EC2自体がリソースを操作する権限を持つイメージです。

PassRoleの設定

では、今回の自動化の運用でどのようにPassRoleを設定していくか、手順を見ていきましょう。この手順ではPassRoleの設定+αの部分も実施しています。+α部分の詳細は手順説明の中でお話しします。

まずは①にて、Jenkinsマシンに適用するIAMロール「AdminEnvRole」を作成します。つまり、Jenkinsマシンがかぶるヘルメットの作成です。このヘルメットには、現時点ではなにもポリシーを付与せず、権限がゼロの状態で作成します。

次に②にて、先ほど作成したヘルメットに「PowerUserAccess」ポリシーを付与します。これでヘルメットをJenkinsマシンがかぶると、管理者用アカウント内にAWSリソースを作成できるようになります。

③にてさらにこのヘルメットに権限を付与していきます。今回は「AmazonSSMManagedInstanceCore」ポリシーを付与しています。これはEC2インスタンスから「SystemsManagerサービスコア機能」を使用できるようにするためのポリシー。おまじないみたいな位置づけのポリシーになります。

④から+α部分の設定手順になります。Jenkinsマシンは管理者用アカウントの環境へのリソース作成のほかにも、AさんアカウントやBさん用アカウントへのアカウント切り替え、AssumeRoleも行えないといけませんよね。ということで、Aさん用アカウントやBさん用アカウントが持つ「ManageEnvRole」にAssumeRoleできるポリシーを作成したいと思います。そして、ここで作成したポリシーを次のスライドで使用します。

⑤では、Jenkinsマシンがかぶるヘルメットに、前のページで作成した「AllowAssumeRolePolicy」を付与しています。⑥では、ようやくJenkinsマシンにヘルメットをかぶせる設定を行っていますね。今回は紫色のヘルメットにしています。この時点でJenkinsマシンは管理者用アカウント内にAWSリソースを作成できるようになっています。

このページが最後の手順です。⑦では、Aさん用アカウントやBさん用アカウントといった受講者用アカウントに作成した「ManageEnvRole」の設定を変更しています。黒塗り潰し部分は管理者用アカウントのアカウントIDになっています。

変更前は、管理者用アカウントのrootユーザーからのみManageEnvRoleへのAssumeRoleを許可していました。変更後は、管理者用アカウントのAdminEnvRoleからのみManageEnvRoleへのAssumeRoleを許可するようにしています。

つまり、AdminEnvRoleを適用したEC2、言い換えれば紫のヘルメットをかぶったJenkinsマシンからのみAssumeRoleが可能な設定へと変更したということになります。紫のヘルメットをかぶったものだけが、緑のヘルメットや赤のヘルメットをかぶることができる。こういったイメージで思ってもらえればと思います。

これにて弊社マネージャーからつっこみのあった「これやったの誰?」への対応がすべて完了しました。管理者用アカウントにリソースを作成しているのは、PassRoleを適用された紫のヘルメットをかぶったJenkinsマシンになります。また、PassRoleを使用しているので、管理者用アカウントのクレデンシャル情報も保持してません。必要ありません。

さらに、PassRoleを適用されたJenkinsマシンしか受講者用アカウントにAssumeRoleできないといった制約もつけられました。これにてようやく「これやったの誰?」のつっこみの対応が無事完了しました。めでたしめでたし。おつかれさまでした。

IaCでの自動化の中では実行アカウントの設計に注意

最後にまとめになります。本日は、AssumeRoleを使用してアカウントの切り替え/切り替えもとの制御が可能なこと、PassRoleを使用してEC2などのAWSサービスにロールを割り当てることが可能なこと、AssumeRoleとPassRoleを使用することでクレデンシャル情報の保持が不要となることをお話ししました。

最後に我々が伝えたい件ですが、スライドに書いてありますように、IaCでの自動化の中では、実行アカウントの設計についても低リスクとなるように自動化担当者が考慮する必要がある点になります。みなさまもIaCで自動化される際にはぜひ心に留めておいてもらえればと思います。

最後までご視聴いただき、ありがとうございました。クラウドネイティブに関するお問い合わせは、お気軽に弊社カサレアルにご相談ください。ありがとうございました。