無印吉澤

Site Reliability Engineering(SRE)、ソフトウェア開発、クラウドコンピューティングなどについて、吉澤が調べたり試したことを書いていくブログです。

WEB+DB PRESS Vol.132「コンテナ化実践ガイド」はこれからコンテナ化する人必読の記事(のつもりで書きました)

本日12/24発売のWEB+DB PRESS Vol.132に、私が執筆した「コンテナ化実践ガイド」が掲載されました! 今までいろいろ文章を書いてきましたが、実は、書店に並ぶ雑誌に記事を書いたのは初めてです。ドキドキしながら発売日を待ってました。

gihyo.jp

ちなみに、電子版がほしい方はGihyo Digital PublishingのEPUB/PDFセットがおすすめです。

gihyo.jp

想定する読者は?

歴史の長いシステムで、モノリシックなアプリケーションを開発・運用している方に向けて、コンテナ化を進めるためのステップを具体的に解説したガイドです。

ここまで具体的に(悪く言えば泥臭いことを)説明している資料は、少なくとも僕は見たことがないので、これからコンテナ化に着手する人には必ず役立つと思います。「うちのシステムをコンテナに乗せて、本当に動くのか……?」と悩んでいる方に是非読んでほしいです。僕がBacklogのコンテナ化に着手する前に読みたかった記事を目指しました。

また、「絶対コンテナ化しなきゃ駄目!」とは書いていなくて、こういう場合はコンテナ化以外の改善をしたほうがいい、という話もしているのでご安心ください。

逆に、「モダンなアプリケーション開発をしているから、なにも苦労しなくてもコンテナに乗りますよ」という方にとっては、この記事のガイドは過剰かと思います。まあ、最近だと、そういう方は最初からコンテナを使ってますよね……。

どういう記事なの?

以下の全5章で構成されています。1章で、この記事で言う「コンテナ化」とはなにかを丁寧に説明してから、2〜5章でコンテナ化の具体的な進め方や、ありがちな落とし穴を説明しています。

  1. あなたのシステムにコンテナ化は必要か?
  2. コンテナ化の計画を立てる
  3. アプリケーションを改善する
  4. アプリケーションをコンテナで動作させる
  5. 本番環境にリリースする

この記事では、僕がBacklogのコンテナ化を実際に行った際の経験から、コンテナ化プロジェクトを以下の4つのフェーズに分けました。2〜5章は、これらの各フェーズに対応しています。

計画フェーズ、改善フェーズ、コンテナ化フェーズ、リリースフェーズ
コンテナ化プロジェクトを構成する4つのフェーズ

1〜2章を読んでもらえれば、僕が考えるコンテナ化プロジェクトの進め方は理解してもらえると思います。3〜5章はさらに具体的な話になるので、実際にコンテナ化することになったら読む、というのでもOKです。

Backlogのコンテナ化って?

僕はヌーラボという会社で、Backlogというプロジェクト管理ツールのSREを5年以上担当してきました。

Backlogには、そのトラフィックの約9割を処理するモノリシックなWebアプリケーションがあるのですが、以前はこれがEC2インスタンス上で動いていました。このアプリをコンテナ化するプロジェクトを2021年4月〜2022年8月に実施し、現在はAmazon EKS上で動いています。

このプロジェクトは本当に最後の最後まで、未知の問題が発生するんじゃないかとビクビクしながら進めました。コンテナ化を進めていくうちに、既存のアプリケーションの問題がいくつも新たに見つかり、上記のフェーズ分けを当てはめるなら「改善フェーズ」がどんどん伸びていって、これは本当に無事に終わるのかと……。

改善フェーズの終了時期がコンテナ化フェーズの終了時期まで伸びている
コンテナ化フェーズの前に終わると思っていた改善フェーズがどんどん伸びていく様子

しかし、そんなプロジェクトも無事に終わり、いまはBacklogを構成するその他の細かいアプリケーションサーバのコンテナ化を進めています。それらの活動から得られた知見をもとに、今回のWEB+DB PRESSの記事を執筆しました。

WEB+DB PRESSの記事では、このBacklogのコンテナ化自体については詳しく触れていないので、もしご興味のある方はSRE NEXT 2022発表スライド発表動画をご覧ください。

執筆のきっかけとSRE Lounge/SRE NEXTへの感謝

今回のコンテナ化実践ガイドは、今年5月のSRE NEXT 2022の発表をきっかけに、技術評論社の池田さんからお声がけいただいて書くことになりました。SRE Lounge/SRE NEXTのようなSREのための情報共有の場は貴重だと思い、長い間スタッフとして参加してきましたが、今回はその貴重さを改めて強く実感しました。スタッフの皆さんいつもありがとうございます。

ちなみに、池田さんから最初にお声がけいただいたのは6月だったのですが、そのときはまだコンテナ化が終わっていませんでした。コンテナ化が無事に終わってから企画会議でOKをもらって書き始めて、12月の雑誌掲載となりました。

昔、研究者だった頃は、こういう雑誌に記事を書けるくらいの有識者になりたいと思ってたものですが、そんなことをすっかり忘れた今になってお声がけいただいてビックリしました。人生なにがあるかわからないもんですね……。

ちなみに

このブログ記事はヌーラバーブログリレー2022の24日目でした。最終日となる明日はAya Yoshidaさんの担当です。そちらもお楽しみに!

ヌーラボ在籍時に書いたブログ記事&プレゼン資料まとめ

2017年8月にヌーラボに入社してから、SRE 関係のブログ記事やプレゼン発表をいろいろ行ってきました。徐々に SRE メンバーが増えていくフェーズで入社したため、特に SRE の組織に関する話を多く書いてきました。

それらの記事がヌーラボブログBacklog ブログとこの個人ブログに散らばってしまっていて、自分でも探すのが大変になってしまったのでここにまとめておきます。

目次

入社直後

入社前からWiki に関する記事 をいろいろ書いてきた関係で、入社直後の研修でサル先生の Wiki 入門(旧:サルでもわかる Wiki 入門)を執筆し、このサイトのインフラ構築もしました。

nulab.com

その後は、徐々に SRE 業務に慣れていったのですが、その時期に行った改善についての記事も書いてます。

nulab.com

他には、kintone devCamp 2018Mackerel Drink Up #8 でプレゼンをさせてもらう機会がありました。

2015 〜 2018 年の Backlog SRE チームの変遷

SRE としての働き方が落ち着き、SRE 組織のあり方について考えるようになった頃に、SRE Lounge #5 で発表をさせてもらいました。自分の入社前のことについては、間違った情報を発信してしまわないように、僕の入社前からいたメンバーに何度もヒアリングさせてもらいました。

muziyoshiz.hatenablog.com

また、SRE Lounge #5 では時間の都合で話しきれなかったサービスレベル計測の話題についても、別の記事にまとめました。

nulab.com

ちなみに、この SRE 組織のあり方については、SRE lounge #5 の発表後に少し考え方が変わりました。そのことはまた別の記事にまとめています。

muziyoshiz.hatenablog.com

Backlog Play 化プロジェクト

2018年4月から2019年7月まで、Backlog を Java & Tomcat から Scala & Play Framework に移行する大規模なリプレイスプロジェクトに参加していました。このプロジェクトからは色々な気付きが得られて、多くの改善を行いました。それらを2回のブログ記事に分けて書きました。

backlog.com

backlog.com

Backlog の課題検索機能のリプレイスプロジェクト

Play 化プロジェクト以降は、改善プロジェクトでプロマネをしながら手を動かす、という働き方が増えました。これはその最初のプロジェクトでした。

このプロジェクトでは、いろいろな課題があった Backlog の課題検索機能を、Amazon Elasticsearch Service を使った新しい実装にリプレイスしました。ステートフルな Backlog アプリケーションをステートレスにし、将来的なマイクロサービス化を可能にするためのプロジェクトでした。

backlog.com

NuCon 2020 でも、このリプレイスプロジェクトと、プロジェクト後の継続的な改善について話しました。

nulab.com

技術面では、Amazon Elasticsearch Service の認証・認可まわりにすごく悩まされて、ついカッとなって個人ブログにまとめたりしました。

muziyoshiz.hatenablog.com

Amazon Linux 2 への移行プロジェクト

2020年は主に、Backlog のたくさんあるサーバをすべて Amazon Linux 2 に移行するプロジェクトを進めていました。技術的な新しさは少ないのでどうまとめようか悩んだ結果、プロジェクトの進め方に焦点を当ててブログ記事を書きました。

nulab.com

インシデント対応のセルフサービス化

Backlog開発チーム自身によるオンコール対応を支えるアラート通知システム からのさらなる改善事例として、「インシデント指揮者」としての役割を開発チームに引き継ぐための活動について書きました。SRE 本および SRE ワークブックを参考に、「インシデント対応チェックリスト」というものを考案し、2021年7月から導入しました。

nulab.com

モノリシックアプリケーションのコンテナ化

SRE NEXT 2022での発表

2021年からは、今までの改善活動の集大成として、Backlog のコンテナ化および Amazon EKS への移行に取り組みました。色々な問題に苦しめられたのですが、約1年かけて解決することができたため、その問題解決の経緯をまとめて SRE NEXT 2022 にて発表しました。

長年運用されてきたモノリシックアプリケーションをコンテナ化しようとするとどんな問題に遭遇するか?(SRE NEXT 2022オフィシャルサイト)

ヌーラボのプロジェクト管理ツール“Backlog”のWebアプリケーション部分は、モノリシックアプリケーションとして開発されてきました。Backlog SREは、開発効率の改善などを目的として、このアプリをAmazon EKSに移行するためのコンテナ化を進めています。 10年以上開発されてきたモノリシックアプリケーションをコンテナ化するにあたり、運用を考慮すると、アプリ自体を改修しなければ解決できない問題がいくつも見つかりました。 この講演では、自社アプリのコンテナ化を検討している方に向けた事例情報として、このコンテナ化プロジェクトで私達が遭遇した問題とその解決方法をご紹介します。また、コンテナ化の完了に向けた今後の計画と、コンテナ化の先に見据える理想像についてもお話しします。

プロジェクト完了後の情報発信

SRE NEXT 2022の発表時点ではまだEC2インスタンスからコンテナへと切り替えている最中だったのですが、2022年7月にコンテナへの切り替えおよびEC2インスタンスの削除が無事完了しました。このコンテナ化プロジェクトで得られた知見を、以下のブログ記事で発信しました。

nulab.com

AWSの薄い本シリーズ(IAMのマニアックな話など)の読書メモ

年明けから IAM 周りの整理をいろいろしなければいけなくなったので、佐々木拓郎さんの「AWSの薄い本」シリーズ2冊を読みました。今回はその読書メモです。

booth.pm

booth.pm

AWS は普段から使っているので、IAM の基本的な機能はもちろん知っているのですが、最近追加された機能(特にマルチアカウント管理に関する機能)については全然追えてなかったので勉強になりました。

以下、勉強になった点をまとめたメモです。AWS の情報は日々変わっていってしまうので、発行日も併せて記載しました。

AWSの薄い本 IAMのマニアックな話(発行日:2019年9月22日)

第1章 AWSとIAM

第2章 IAMの機能

  • IAMの機能のうち、まず次の5つの機能の認知と理解をしておくことが重要
    • IAM ユーザー
    • IAM グループ
    • IAM ポリシー
    • IAM ロール
    • パーミッション・バウンダリー
  • アクセスキーの発行は原則しないほうがいい。必要になったときに最小の権限で発行する
  • IAMユーザーに権限を直接付与こともできるが、管理上の複雑さが増すので、IAMグループで管理することを推奨
  • 管理ポリシーとインラインポリシー
    • インラインポリシーは管理ポリシーができる前の古い機能
    • AWSが最初から設定しているポリシーをAWS管理ポリシー(AWS Managed Policies)、各ユーザーが独自に作成したポリシーをカスタマー管理ポリシー(Customer Managed policies)と呼ぶ
    • AWS管理ポリシーで大まかな権限を足した後、不要な権限をカスタマー管理ポリシーで引く
  • Permissions Boundary(パーミッション・バウンダリー)
    • 2018年7月に登場した、IAMの移譲権限を制限する機能
    • 他者にIAMユーザーやIAMロールを貸与する際に、それらが持つ権限の一部(パーミッション・バウンダリーで設定した権限)しか使えない状態にすることができる

第3章 IAMチュートリアル

  • Condition で aws:SourceIp を指定するときに、プライベート IP の範囲を指定しても意味がない。VPC 内のリソースを制限するには VPC ID もしくは VPC Endpoint ID を指定する必要がある(6章)
  • IAM ポリシーの基本的な動作は「明示的な Deny > 明示的な Allow > 暗黙的な Deny(デフォルト)」
  • クロスアカウントロール(IAM ロール)を使って、設定変更時のみ、変更権限を持つ IAM ロールにスイッチする例
    • スイッチ元は sts:AssumeRole で制限
    • Principal に、IAM グループでの指定はできない

第4章 IAMポリシーのデザインパターン

  • ホワイトリストパターン
    • 最小権限を付与するのに適している
    • 事前に役割を決めて権限を付与するため、探索的な開発の場合には効率が悪くなる
    • 本番環境、かつ高いセキュリティを求められるエンタープライズ向け
  • ブラックリストパターン
    • 禁止事項のみを定義すればよいので、IAM ポリシーの設計・設定が最小で済む
    • AWS に新しいサービスが始まると、予期せぬ機能が突然使えるようになる
    • 探索的な開発環境、もしくは比較的大きな権限が必要な管理者向け
  • ハイブリッド・パターン
    • AWS の定義済みのポリシーと、自分で作ったブラックリストを組み合わせて利用することで、最小の労力で実用的なポリシーを作ることができる
    • 組み合わせに使われる個々のポリシーは、シンプルに作ることができる

第5章 IAMグループのデザインパターン

  • 以下の2つのパターンが考えられるが、機能的な優劣はない
    • ユーザーが複数グループに所属し、グループ間のポリシーの重複はないパターン
    • ユーザーが1つのグループに所属し、グループ間でポリシーの重複があるパターン
  • IAMグループは、path オプションを使って階層構造を表現できるが、権限の継承のような機能はない

第6章 IAMとセキュリティ

  • AWS が公開している IAM のベストプラクティス
  • 特権ユーザーに関わらず、すべての IAM ユーザーに対して MFA の有効化を原則にすべき
  • ユーザー自身のパスワードと MFA の設定を許可する例
    • ${aws:username} は IAM ポリシーエレメントと呼ばれる変数で、ログインしている IAM ユーザー名に置き換えられる
    • AWS アカウント ID の変数は、IAM ポリシーエレメントに無い。代わりに、CloudFormation の疑似パラメーター参照に AWS::AccountId として存在する
  • Lambda のリソースベースポリシー
  • インターネット公開系の権限(EC2のインスタンスへの通信許可など)は、ホワイトリストで管理するのは大変。そういった際には、ネットワーク系の操作を明示的に拒否する方法と併用するといい
  • S3 へのアクセス元制限は、IAM ポリシーを使うより S3 側のバケットポリシーを使うのが一般的
  • IAM ユーザーを作成する際の原則として、アクセスキー、シークレットアクセスキーを作らないことを推奨
  • Capital One の情報流出事件(S3 からの情報流出)を防ぐために必要だった設定
    • IAM ロールのクレデンシャルが漏洩した際の影響を最小化するため、IAM ロールに付与する権限を絞り込む
    • バケットポリシーで接続元 VPC を制限する

第7章 IAMの運用

  • IAM 運用の目的
    • AWS を安全な状態に保ち続ける
  • 目的の達成のために
    • 維持するために手間が掛からない(現実に許容できるコスト)
    • 利用者によってセキュリティレベルの差異がでないようにする(標準化)
  • まずは利用者(人間、プログラム)を洗い出す
  • AWS を利用する人ごとに適切な最小権限を付与し、必要でなくなったら権限をなくす
    • CloudTrail で AWS コンソール、API 利用履歴のログを取得する
    • Config を利用し、IAM 関係の設定の変更を監視する
    • Config Rules で設定値を監視
    • (月次等の)定期的な IAM ユーザーの棚卸し
  • CLI やプログラムから利用する IAM ユーザーも、棚卸しが必要
    • IAM ユーザーごとの担当者を明確化する
      • 例えば、IAM ユーザーのタグに担当者を書く
    • 最終利用日から一定時間が過ぎた IAM ユーザーは継続の確認をする
      • 使われていなければ、まず無効化して、しばらくして問題がなければ消す
  • CLI 利用のためにアクセスキーを発行する場合、アクセスキーの流出対策が必要
    • CLI 利用時にも IAM ロールへの切り替えが可能
    • IAM ユーザー側に IP アドレスによる利用制限をした上で、必要な場合にスイッチロールで権限を切り替えるという運用をしておけば、万が一流出しても直接の被害を防げる
  • マルチアカウント利用時は、各アカウントに IAM ユーザーを作るのではなく、踏み台 AWS アカウントを1個作り、そこの IAM ユーザーから、他のアカウントのロールにスイッチする

第8章 IAMとCloudFormation

  • 複数の AWS アカウントに、同じようなポリシーやロールを作る場合、CloudFormation 化しておけば人的ミスを排除できる
  • IAM ユーザーは基本的に一度作っておしまいなので、CloudFormation のライフサイクルで管理するメリットがほとんどない。そのため管理対象から外すことを推奨する

第9章 IAMのテンプレート集

  • 本書のテンプレート集のダウンロード URL
  • 管理者グループには IP 制限を加えるべきだが、IP 制限があると CloudFormation 等の一部の機能が使えない場合がある。そのため、スイッチロールを指定して IP 制限を解除できるようにしておく
  • 管理者ロールへスイッチできるユーザーを限定する方法としては、以下の2通りがある
    • ロールに、スイッチ可能なユーザーを記載する(本書のテンプレートはこちらを採用)
    • スイッチロールを原則拒否し、必要なユーザーのみスイッチロールの権限を付与する
  • ネットワークに関連する権限は多岐に渡るため、自分でリストアップするのは難しい。職務機能の AWS 管理ポリシー(AWS managed policies for job functions) にある NetworkAdministrator の利用を推奨する
  • 開発者に、EC2 インスタンスを立ち上げるための権限を付与しようとすると、いまや EC2 に IAM ロールを付与するのは必須であるため、IAM ロールの作成・更新に関する権限が必要。そうすると、実質的に何でもできてしまう
    • 現実的な対応としては、開発環境では管理者権限を付与した上でしっかり監査証跡を残す

第10章 IAM以外のAWSサービスの活用

  • AWS Organizations(組織アカウント)
    • ルートと呼ばれるマスターアカウントと、それに紐づく子アカウントがある。また、子アカウントを階層化するための組織単位がある
    • アカウントに対するポリシーと言う形で、ホワイトリスト/ブラックリスト形式で権限の管理ができる
    • 上位で決めたポリシーは、個々のアカウント単位で打ち消すことはできない(強力な統制)
  • CloudTrail と Config
    • CloudTrail と Config は対となるようなサービス
    • CloudTrail は操作ログの記録
    • Config は操作の結果どういう状態になったのかの記録、および状態変更に対するアクションの定義
  • Amazon GuardDuty
    • 脅威検出と継続的なモニタリングサービス
  • AWS Control Tower と AWS Security Hub
    • AWS Control Tower は複数アカウントの設定および管理
    • Security Hub は複数のアカウントの状況を一括してモニタリング

付録A アカウント開設時の設定チェックリスト

  • セキュリティの強化
    • 1) ルートアカウントの MFA 設定
    • 2) IAM Group と IAM ユーザーの作成
    • 3) IAM パスワードポリシーの適用
  • 状況の出力・見える化
    • 4) CloudTrail の有効化
    • 5) Config の有効化
    • 6) GuardDuty の有効化
    • 7) Trusted Advisor の E メール通知設定
    • 8) Cost Usage Report の出力
  • 機能を使うための設定
    • 9) ルートアカウントで IAM User への請求情報へのアクセス許可
    • 10) 支払い通貨を日本円に変更
    • 11) コスト配分タグの設定
    • 12) 代替連絡先の設定

AWSの薄い本Ⅱ アカウントセキュリティのベーシックセオリー(発行日:2020年3月22日)

第1章 AWSアカウントセキュリティ

  • AWS のセキュリティを3つの観点から分類
    • 1) AWS 上に構築するシステムのセキュリティ
    • 2) AWS アカウント自体の管理(IAM の設計・運用)
    • 3) セキュリティを維持管理するための施策
  • 3は、いわゆる AWS アカウントのガードレール設計。本書の中心テーマの一つ
    • IAM を運用しているうちに抜け漏れが出てきたり、カバーしきれない部分がでてきたときに、それらを予防・検知するための施策がガードレール設計
  • 本書では AWS Organizations は基本的には解説せず、その一部の機能であるサービスコントロール Policy(SCP)のみを扱う

第2章 ガードレールという設計と思想

  • Control Tower にはガードレールという機能がある
  • ガードレール設計の思想と、Control Tower が実際にそれをどのように実現しているのか
  • Control Tower は最小構成で3つの AWS アカウントで構成される
    • マスターアカウント
    • ログ管理用アカウント
    • 監査用アカウント
  • 一元管理と改ざん防止のため、ログ管理用アカウントと監査用アカウントが、その他のアカウント(開発環境用や本番環境用)から分離されている
  • Control Tower は、道から踏み外さないための予防と検知を提供する
    • 予防:自分の権限外の操作(例えばログの削除)を禁止する
    • 検知:ルールから外れた操作(例えばルートアカウントの利用)を検知する
  • Control Tower における予防と検知の実態は、Organization の SCP(Service Control Policy)と Config Rules
    • ただし、Control Tower の個々のガードレール名を見ても、予防なのか検出なのかの区別がつかないという欠点がある

第3章 AWSのセキュリティサービス

  • NIST Cybersecurity Framework
  • CSF コア
    • 特定(Identity)
    • 防御(Protect)
    • 検知(Detect)
    • 対応(Respond)
    • 復旧(Recover)
  • NST CSF コアを参照しながら、AWS のセキュリティサービスを整理する
  • CloudTrail のおすすめの設定の一つに、クロスアカウントロールを利用して他のアカウントに対してログを保存するという方法がある
    • システム内で使う証跡情報はローカルの S3 バケットに保存し、監査用に集積する証跡情報は監査用 AWS アカウントのバケットに保存する
    • こうすることにより、プロジェクトごとの利便性と、組織全体のガバナンスの両方を確保できる
  • GuardDuty の分析対象は、CloudTrail、VPC フローログ、DNS ログの3種類
  • Trusted Advisor は便利だが、現在は通知方法がEメールしか使えない

第4章 サンドボックスアカウントの作成のチュートリアル

  • 実験や検証に使う AWS アカウントのことを、本書ではサンドボックスアカウント(サンドボックス環境)と定義する
  • 今回作るサンドボックス環境の要件
    • 1) アカウントの利用者は一人(多人数でアカウントを共有しない)
    • 2) 利用者はそのアカウント内では、ほぼ全ての権限を持つ(管理者権限)
    • 3) 外部への情報漏えいにつながる行為、権限付与を禁止する
    • 4) 問題となる行為を定義し、自動で検知・通知できるようにする
    • 5) 問題検知時に通知だけでなく自動復旧を目指す
  • 3の設定項目については、以下の4項目に具体化して考える
    • IAM ユーザーの新規作成禁止
    • アクセスキーの作成禁止
    • S3 のパブリックアクセス禁止
    • 不特定多数へのセキュリティグループ開放禁止
  • IAM Access Analyzer を有効にする
  • マスターアカウント側で CloudTrail の設定をして、メンバーアカウントから設定や削除ができないようにする
  • Config アグリゲータの設定をして、マルチアカウント・マルチリージョンで Config のデータを集約する
  • Security Hub を有効化する
  • Config Rule は登録時に設定した間隔で定期的にチェックされる(デフォルト12時間、最短1時間)
  • 自動復旧は、複雑な処理が必要な場合は Lambda でスクリプトを書き、定形処理で済む場合は AWS System Manager(SSM)の Automation を使う
  • SCP の使い方としては、現状の仕様では "Effect": "Allow" を利用せず、"Effect": "Deny" で禁止すべき項目を設定していくほうがよい

第5章 CloudFormation を利用した構成管理

  • CloudFormation StackSets は、1つのテンプレートから複数の AWS アカウント・リージョンに対してスタックの作成・実行ができる機能
  • 2020年2月12日に機能が追加され、Organizations からアカウントの作成・削除時や OU の移動時に指定しておいた StackSets を自動で実行できるようになった

第6章 アカウントセキュリティの設計の考え方の原則

  • AWS Well-Architected フレームワーク(現時点の最新版は2020年7月)
  • NIST CSF コアと、AWS Well-Architected Framework を比べながらの解説
  • SEC 8「データをどのように分類していますか?」に該当する機能に、AWS Macie(機密データを検出、分類、保護するサービス)がある

第7章 障害の検知と復旧の考え方

  • AWS に多数あるセキュリティ関係のサービス同士の関係についての解説
    • 似たようなサービスもあるが、それをどう取捨選択するか
  • Security Hub と個別サービスの使い分けはシンプル
    • システムの運用に関わる障害は、アカウント個別に設定
    • AWS アカウントに対する攻撃については、複数のアカウントで共通設定

第8章 まとめとマルチアカウント管理への道

  • 本書全体のおさらい
  • 予防的統制(Preventive controls)と発見的統制(Detective controls)

Amazon Linux 2 に awscurl を安全にインストールする簡単な方法

f:id:muziyoshiz:20201129180845p:plain

この話の背景

以前のブログ記事で、Amazon Elasticsearch Service を awscurl(AWS 署名に対応した curl ライクなコマンド)経由で管理する方法をまとめました。

muziyoshiz.hatenablog.com

自分が扱っている環境では、管理用サーバ(Amazon Linux 2)に awscurl をインストールして使ってます。

この管理用サーバで使う Python 製のツールは awscurl だけだったので、Amazon Linux 2 標準の Python 2 に pip install awscurl して使ってたんですが、そしたら yum update を実行するたびに urllib3 のアップデートと衝突して使えなくなることが頻発。

まあ、Python 知っている人にしたら「それはそう」って話なんですけど、awscurl を使いたいだけだからいいか、とサボってたんですよ……そしたら案の定という感じ。このためだけに pyenv 入れるのは面倒だなあと悩んでいたら、同僚にいい方法を教えてもらって解決したのでまとめておきます。

結論:pipx 経由で awscurl をインストールする(ただし Python 3 が必要)

pipx とは、Python で書かれたエンドユーザーアプリケーションを、独立した環境で動かすことができるツールです。

github.com

コマンド名からお察しの通り、pipx は pip と同じく The Python Package Index (PyPI) を使えます。それに加えて、pipx はインストールしたツールが依存するパッケージを、ツールごとに独立した環境にインストールしてくれます。アップグレードやアンインストールも、同様にクリーンな環境で行なえます。

サイト内の説明を借りると、いわば pipx は PyPI を Python アプリケーションのための巨大な app store にしてくれる(In a way, it turns Python Package Index (PyPI) into a big app store for Python applications.)というわけです。いいですね。

ただし、pipx の動作には Python 3 が必須です。しかし Amazon Linux 2 に標準添付されているのは Python 2.7 だけ。amazon-linux-extras に Python 3 系があるので、細かいことを考える必要がないなら、これで Python 3 系を入れてしまうのが一番楽でした。

以下、awscurl のインストールが完了するまでの具体的な手順です。

インストール手順

Python 3 のインストール

amazon-linux-extras に関する説明はこちら。これは AWS が Amazon Linux 2 用に管理している yum リポジトリを有効にするコマンドです。ソフトウェアのインストール自体は yum コマンドで行います。

aws.amazon.com

amazon-linux-extras 自体が未インストールの場合は、まず以下のコマンドでインストール。

$ sudo yum install -y amazon-linux-extras

amazon-linux-extras コマンドで、現在利用できるリポジトリ(amazon-linux-extras の用語ではトピック)の一覧が確認できます。現時点では python3.8 が利用できることがわかります。

$ amazon-linux-extras | grep python
 44  python3.8=latest         available    [ =stable ]

そこで、今回は python3.8 のリポジトリを有効にしてから、yum コマンドでインストールします。将来、Python のバージョンが上がったら、python3.8 の部分は読み替えてください。

$ sudo amazon-linux-extras enable python3.8
$ sudo yum install python3.8

pipx のインストール

pipx のインストールは、pipx サイト内の手順 のコマンド名を python3 から python3.8 に置き換えれば OK です。

$ python3.8 -m pip install --user pipx
$ python3.8 -m pipx ensurepath

これで、そのユーザー(EC2 だと ec2-user)は特別なパス指定なしで pipx を使える状態になりました。pipx のインストール先は ~/.local/bin/pipx です。

pipx 経由での awscurl のインストール

awscurl のインストールは、従来の pip を pipx に置き換えるだけで OK です。

$ pipx install awscurl

awscurl のコマンドは ~/.local/bin/awscurl にインストールされますが、awscurl が依存するパッケージ一式は ~/.local/pipx/venvs/awscurl/ 以下にインストールされます。このように、ツールごとに環境が分離されるわけですね。

注意点:シェル変数の扱いが変わる

コマンドごとに環境が分離されるためか、シェル変数の扱いが変わるようです。

以前のブログ記事 では、awscurl コマンドへ自動的に認証情報を渡す awscurl-on-ec2 というシェルスクリプトを紹介しました。

#!/bin/env bash

ROLE_NAME=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/`
CRED=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}`
AWS_ACCESS_KEY_ID=`echo $CRED | jq -r ".AccessKeyId"`
AWS_SECRET_ACCESS_KEY=`echo $CRED | jq -r ".SecretAccessKey"`
AWS_SESSION_TOKEN=`echo $CRED | jq -r ".Token"`

awscurl "$@"

pipx でインストールした awscurl には、この方法ではシェル変数が渡されませんでした。以下のように、export を使って環境変数にすれば問題なく渡されました。

#!/bin/env bash

ROLE_NAME=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/`
CRED=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}`
export AWS_ACCESS_KEY_ID=`echo $CRED | jq -r ".AccessKeyId"`
export AWS_SECRET_ACCESS_KEY=`echo $CRED | jq -r ".SecretAccessKey"`
export AWS_SESSION_TOKEN=`echo $CRED | jq -r ".Token"`

awscurl "$@"

awscurl の場合はコマンドライン引数を使って、これらの認証情報を明示的に渡すこともできます。環境変数を増やしたくなかったので、自分はこちらの方法で対応しました。

#!/bin/env bash

ROLE_NAME=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/`
CRED=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}`
AWS_ACCESS_KEY_ID=`echo $CRED | jq -r ".AccessKeyId"`
AWS_SECRET_ACCESS_KEY=`echo $CRED | jq -r ".SecretAccessKey"`
AWS_SESSION_TOKEN=`echo $CRED | jq -r ".Token"`

awscurl --access_key $AWS_ACCESS_KEY_ID --secret_key $AWS_SECRET_ACCESS_KEY --session_token $AWS_SESSION_TOKEN "$@"