fu3ak1's tech days

何事もシンプルに。主にAWS関連の記事を書いています

Chatbotと時間限定IAMポリシーを使用した本番接続運用を考える

こんにちは。上野と申します。

Japan APN Ambassador Advent Calendar 2020 10日目のエントリです。AWSさんに挟まれた日程で記事を書いております。ほかの方の記事も、おもしろいものばかりですので是非読んでみてください。

Ambassadorって何?というかたは下記の記事を読んでもらえるとわかると思います。

APN Ambassadorってなんだ? - Qiita

私は2020年にAmbassadorとして選んでいただきました。資格取得や登壇、執筆などが評価され、選出いただいたと考えています。

本エントリの内容について

私は技術的なネタを書きます。

コロナウィルスの影響で在宅勤務が増えるなか、みなさま本番システムのアクセスはどう管理していますでしょうか。 オフィス内に本番接続ルームを用意して、そこからアクセスするという運用をされている方も多いと思います。

ただ、今後もコロナの状況が続くとなると、中々オフィスに出向くのは厳しいかもしれません。そこで私からは本番アクセスの一例として、Chatbot時間限定IAMポリシーを使用したアクセス運用を紹介したいと思います。

実際に運用で使っているわけではなく、私の1アイディアですので参考として読んでいただけると幸いです。

使用するサービスについての前知識

Chatbot

Chatbotは、SlackやAmazon ChimeのチャットツールとAWSを連携するサービスです。チャットでメッセージ送信をトリガーにLambda関数を実行できるため、今回はそれを使用します。

なお、Chatbotを準備してLambda関数を実行するまでの内容は以下記事で解説しています。

fu3ak1.hatenablog.com

時間限定IAMポリシー

IAMポリシーには、ConditionにDateLessThanを指定することで、時間限定のAWSアクセスを付与できます。 今回はこれを使用して一時的なアクセスをユーザーに付与します。

「IAMポリシーの例」

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "DateGreaterThan": {"aws:CurrentTime": "2020-04-01T00:00:00Z"},
                "DateLessThan": {"aws:CurrentTime": "2020-06-30T23:59:59Z"}
            }
        }
    ]
}

参考: AWS: 日付と時刻に基づいてアクセスを許可する - AWS Identity and Access Management

運用方法(利用時)の流れ

技術的な点は一旦置いておいて、どのような流れで一時アクセスを付与するのか流れで説明します。

1.デフォルトの状態=何もできない

デフォルト状態では、IAMポリシーを空にしておき、IAMユーザーはログインのみできる状態にしておきます。

f:id:fu3ak1:20201208215626p:plain

この状態でログインしてEC2の画面を表示すると、以下のとおりAPIエラーとなり各種情報が表示されません。 本番の運用状況にもよりますが、例えばデフォルトRead権限はつけておくというポリシーもありかと思います。

f:id:fu3ak1:20201208215744p:plain

2.Slack経由でIAMユーザーに権限を付与する。

IAMユーザーが本番アクセス(AWSへログイン)が必要になったとします。 管理者がSlack上に↓のメッセージを実行することで、指定したユーザーに権限が付与されます。 ここではユーザー名をprd-userとします。--payloadオプションでIAMユーザー名を指定しています。

@aws lambda invoke temp-access --payload {"user":"prd-user"}

すると以下の通りChatbotが実行するか質問してくるので、Yesを押します。

f:id:fu3ak1:20201208223239p:plain

Lambdaが実行されます。「End time is・・」に記載されている時刻は、 IAMユーザーのアクセスが不可となる時間です。(UTCで表示されてます)

※時刻の設定やレスポンスはLambda内でもろもろ実装

f:id:fu3ak1:20201208223340p:plain

この時点でアクセス権限が付与されました。

f:id:fu3ak1:20201208222651p:plain

3.IAMユーザーログイン

アクセス権限が付与されたので、アクセスしてみます。

以下のように、先ほどAPIエラーとなっていた各数値の情報が表示されました。 これでアクセスが可能になったことがわかります。

今回はIAMユーザーにAdministratorAccess同様(全許可)のポリシーを時間限定で付与しています。 実運用では、本番運用に必要な権限のみ許可するほうが良いでしょう。

f:id:fu3ak1:20201208221504p:plain

4.指定時間経過後

指定した時間が経過すると、以下のようにまた情報が表示されなくなります。特に再ログインは無しで、画面遷移していると急にエラーになります。

そのため設定する利用時間は慎重に設定する必要があります。また、ChatbotからLambdaを再実行すれば期間延長可能です。

f:id:fu3ak1:20201208222304p:plain

運用方法はここまでです。

技術情報の補足

ソースコードは以下githubに置いています。 CloudFormationテンプレート(CreateTempIAMPolicy.yml)をデプロイすれば、Lambda関数が作成されます。 Chatbot経由のLambda実行は繰り返しになりますがこちらの記事を参考にしてください。

github.com

アーキテクチャは以下の通りです。 LambdaがIAMポリシーを付与するだけという、割とシンプルなつくりです。

f:id:fu3ak1:20201208224012p:plain

その他いくつか実装面の補足情報を書いておきます。

  • 利用可能な時間は、Lambda関数の環境変数で設定しています。CloudFormationテンプレートのデフォルトは180で、単位は分です。(3時間)
  • IAMポリシーはIAMユーザーにインラインポリシーとして設定しています。通常ポリシーを一元管理にするために、管理ポリシーを付与してそれをIAMグループに付与するのが一般的ですが、今回は指定したユーザーのみに付与するためインラインにしました。
  • 指定時間が経過しても、インラインポリシー自体は残り続けます。ただし時間切れ状態です。再度Lambda関数が実行されると、ポリシーが新しい時間で上書きされます。

実運用上での考慮事項

実際の本番運用で使う場合は、この実装だけでは足りず、追加で考慮も必要になるかと思います。 いくつか検討事項として出てきそうなところを書いてみます。

IAMポリシーについて

運用方法の流れでも書いたとおり、例では許可するActionとResourceを*(=全許可)で指定しているため、実際の運用では本番運用で必要な権限のみ指定して許可する必要があります。 また、IAMポリシーではIP制限をかけたり、MFAを強制させることもできますので、そういった追加のセキュリティポリシーを追加するとよりセキュアなアクセスが実現できます。

本番持ち出しについて

IP制限など、特定の端末にアクセスを絞らない場合は、データの端末への持ち出しが気になるところです。以下は1つの例ですが、WorkSpacesを本番アクセス仮想端末として使用することで、ファイルの端末への書き出しを防ぐことができます。

WorkSpacesへのログインは、クライアント証明書ベースの認証もできるので、証明書が入った端末のみアクセス可能といった制御もできますね。

f:id:fu3ak1:20201208232102p:plain

VPC内へのアクセスについて

VPC内にEC2を多く配置していると、EC2にSSHでログインすることもあるかと思います。

私としては、サーバーに直接SSHアクセスするのではなく、Systems ManagerのSession Managerを使用してサーバーアクセスするのが良いと思います。こうすることでサーバアクセスの認証もIAMで一元管理できるからです。操作ログも取得も可能です。Session Managerの使い方はこちらに書いています。

Chatbotの利用について

今回、Slackの特定のチャンネルからChatbotを実行できるようにしているのですが、このチャンネル内のユーザーであれば誰でもLambda関数が実行可能となります。そのため、管理者のみのプライベートチャンネルにしたほうが良いです。

Lambda側で呼び出したSlackユーザー情報が取れれば、ユーザーに応じて処理実行有無を制御できるのですが、現状Slackユーザー情報は取得できないようです。

まとめ

すいません、なんだか長くなってしまった気がします。

本番運用されている方、アクセス方法に悩まれている方も多いかと思いますので、何かの参考になれば幸いです。

今回ご紹介したのは1つの手段です。アクセス手段を作ることは目的ではなく、本番上の情報を守ることが本来の目的かと思いますので、どういったら守れるのか、そういった観点でアクセス方法も考えていきたいですね。

ありがとうございました、明日のアドベントカレンダーもお楽しみに!!

re:Invent2020セッションレポート :(BLD207) Hands-off: Automating continuous delivery pipelines at Amazon

概要

Amazonにおける継続的デプロイ(CD)自動化の事例紹介です。 この内容はThe Amazon Builders' Libraryの記事にも掲載されており、基本的にはそれと同じ内容です。 ブログのほうが詳細な部分もある気がしますが、セッションでは人の説明を聞くことでよりわかりやすい部分もあったかなという印象です。

aws.amazon.com

内容

スピーカーのClareさんもAmazonに来る前はVery manual(手動)だとおっしゃっていましたw

  • AWSサービスのCDパイプライン例、多くのStageあり

f:id:fu3ak1:20201203223304p:plain

Balance safety and speed deployments

  • 本番リリースは安全に行いたい、でもできるだけ早く顧客へ届けたい。バランスが重要
    • スピードを重視すると顧客影響が大きくなる、ゆっくりデプロイすること(例えば1顧客ごと)でリスクは下げられる
  • Amazonのアプローチは、まずは小さい範囲でデプロイ、その後広げる(多くの範囲にデプロイ)

f:id:fu3ak1:20201203223743p:plain

  • パイプラインはマイクロサービス単位で用意、細かく分けることでサービス全体への影響を下げる

f:id:fu3ak1:20201203224208p:plain

  • ただしプロダクションデプロイメントでは影響が出ることも多い、そこでOne-Boxを追加

f:id:fu3ak1:20201203224424p:plain

  • One-Box
    • One-BoxはいわゆるEC2やコンテナを1個ということ
    • 新アプリケーションのインスタンスを1つ用意して、例えば10%という小さい割合で流す

f:id:fu3ak1:20201203224559p:plain

  • 徐々に新アプリインスタンスを増やしていく、最終的に全部入れ替え

f:id:fu3ak1:20201203224814p:plain

  • 更にリスクを低減するためRegion単位でOne-box、デプロイステージを用意
  • ただしこれでも最初のRegionはリスクがあるかもしれない

f:id:fu3ak1:20201203225046p:plain

  • Regionから更にAZ単位に分解

f:id:fu3ak1:20201203225143p:plain

  • AZ単位で全部やってたら遅いよね(最初のスピードとリスクの話も含め)

f:id:fu3ak1:20201203225243p:plain

  • スピードUPのためWaveという概念を投入
  • Waveで並行デプロイを実現
  • 最初の2つは小さいスコープ(1Region)、うまくいったら対象リージョンを増やして並行に

f:id:fu3ak1:20201203225358p:plain

  • 実際の開発現場ではさまざまな機能追加があるため、色々なデプロイが入り混じる。1つ目のパイプライン実行中に次が来るなど
  • Waveではステージごとに独立したデプロイを実現しているため、各ステージでバージョンが異なっても問題ない
  • これにより多数のデプロイを実現している

f:id:fu3ak1:20201203225923p:plain

  • Waveの詳細、1Waveの中身
  • ステージを並行にしているだけで、各ステージあたりのスコープは小さい
  • 1Waveの中で異なるバージョンの混在も可能

f:id:fu3ak1:20201203230156p:plain

Roll back automatically

  • Amazonに入る前は、リリース後メトリクスグラフ(レスポンスタイム)とにらめっこしていた
    • これは異常なのか?など考えながら見ていた
  • Amazonではそれはやらない、hands-off、自動化
  • 開発者がメトリクスを見るのではなく、パイプラインに監視させる

f:id:fu3ak1:20201203230615p:plain

f:id:fu3ak1:20201203230817p:plain

  • パイプラインは多くのメトリクスを見ている
  • リージョン単位、AZ単位、One-Box単位でもメトリクスを見ている

f:id:fu3ak1:20201203231151p:plain

  • フロント、Backend、DBなど各レイヤーが相互に影響することもあるため、それぞれ監視する

f:id:fu3ak1:20201203231457p:plain

  • リリース後、しばらくしてから異常になることもある
  • Bake Timeという期間を設けており、リリース後、Baketime中も監視を継続する
  • Bake Time中にSpike(異常)が発生したら自動ロールバックする。次のステージにも進まない

f:id:fu3ak1:20201206221307p:plain

  • 1つのリージョンで障害が発生すると、on-callエンジニアがその後どうするのか判断する
  • すべてロールバックすることも、そのまま他のリージョンは進めて対象リージョンだけ修正することも可能

f:id:fu3ak1:20201206221509p:plain

  • Amazonでは互換性を大事にしているため、旧フォーマットでの処理ができるか確認する
  • Prepare(準備フェーズ)で、新フォーマットと旧フォーマットを処理して問題ないことを確認する、エクササイズ段階で書き込みは旧フォーマットベース
  • 問題ないことを確認できたら、Activateを行い、書き込みを新フォーマットベースにする
  • (必要であれば)旧フォーマットの処理ロジックをコードから削除する
  • すべてのデプロイが互換性を持ったデプロイができるわけではない

f:id:fu3ak1:20201206222044p:plain

Automate pre-production testing

  • Build段階ではユニットテスト、静的コード解析を行う。IaCではLintersを使用
  • AlphaステージでFunctional tests、コンポーネント単体テスト
  • BetaステージでEnd-to-end tests、システム全体で処理が問題ないか確認する
    • フロント、バックエンド、DBがあればその3層全てを見る
  • Gammaステージでは Production環境に近いテストを実施
    • one-boxを用意してCanaryモニタリング
    • 自動ロールバックの設定、監視しきい値の設定もあり
    • レイテンシーの上昇もここで確認できる
    • End-to-end testsもここでもう一度行う(よりProductionに近い環境で)
    • 本番リリースと同じような処理を行うイメージ

f:id:fu3ak1:20201206223027p:plain

  • 下位互換性を確認するために、Zetaテストを設定することもある

f:id:fu3ak1:20201206223418p:plain

セッションまとめ

  • Hands-off デプロイの主要な戦略はそこまで多くない、それらをどう組み合わせてパイプラインとして構築するか考えている
  • バランスとスピードを取るためにOne-box、AZ、リージョン、Waveという単位でリリース
  • メトリクスベースのアラームを用意して自動ロールバック、リリース後のBaketimeも用意
  • 本番リリース前にひととおりのテストをパイプライン実行する
  • 最初に見せたパイプラインは一見複雑(テキストも小さい)であるが、説明したコアな戦略を理解すれば、そこまで複雑ではない。処理が組み合わさっているだけ
  • builders-libraryも見てね

f:id:fu3ak1:20201206224117p:plain

感想

リリース処理、監視、ロールバック、テストなど自動化レベルの最高峰かなと感じました。 私としてもこういったリリース処理やテスト等はパイプラインに任せたほうが楽になるし、かつ品質も良くなると考えているため、真似できるところは実装してみたいなと思いました。

特にGammaステージの本番同等のテストはなかなか難しいかもしれませんが・・

一方で、ソースコードは徹底的に人の目でレビューをしているところ、on-callエンジニアがいること(親近感)もあり、サービス品質に直結するところはやはり人による対応が必要なんだなと感じました。

また、小さな単位でリリースを行っているとのことでしたが、例えば大規模リリースやキャンペーンなどで全リージョン(もしくは1リージョン)で同タイミングリリースが必要な場合は、また別の工夫点があるのかなと気になりました。

パイプラインの本質を知れたような気がして、とても良かったです。

re:Invent2020セッションレポート:(EMB019) Deep dive on AWS Glue Elastic Views

概要

2020 re:Inventで新たに登場した AWS Glue Elastic Viewsの紹介セッションです。 AWS Glueは既存のサービスで、データ分析用のデータETL(抽出、変換、読み込み )処理や対象データスキーマ管理に使用されます。

今回はGlueの新機能としてElastic Viewsが出ました

Why AWS Glue Elastic Views?

  • 従来の仕組みはアプリケーション+データベースの2層構成
  • オンラインショップを例とすると、オーダー情報や個人情報を元に、不正検知やレコメンデーション等色々な処理が必要になる。
  • 1つのDBではこれら色々な処理をするのは難しい

f:id:fu3ak1:20201204161821p:plain

  • AWSでは目的ベースでDBサービスが用意されている
  • オンラインショップの場合もやりたい処理内容に合わせてDBを選択する

f:id:fu3ak1:20201204161927p:plain f:id:fu3ak1:20201204162005p:plain

  • ショッピングカタログを例

    • 100万人ユーザー、100万RPS
  • おそらくこういった例ではDynamoDBを使用する

f:id:fu3ak1:20201204162217p:plain

  • もしこのアプリケーション(+DB)が稼働中で、テキスト検索がしたいという要件が出たらどうするか?
  • テキスト検索に特化したElasticSearchを用意して、DynamoDBから読み込む
  • コピー処理には複雑なコードが必要で、エラーのリトライ管理、パイプラインの管理もしなければいけない→大変

f:id:fu3ak1:20201204162328p:plain

  • そこでGlue Elastic Viewsの登場!

f:id:fu3ak1:20201204162524p:plain

What are Glue Elastic Views

  • Elastic Viewsとは
    • 複数のデータソースを組み合わせてレプリケートし、マテリアライズドビューをコードなしで作成する
    • Transformもしてくれる
    • 簡単に使える、コード作成や管理が不要
    • PartiQLの仕組みを使用して、ビューの定義を利用者が指定して作成する。
    • トランザクション整合性、オーダー(順番)がCorrect(保証する)
    • データ変換も正しく行える、用意されたデータタイプも多い
    • "ほぼ"リアルタイム(Near-real)
    • 暗号化されており、IAMを使用するのでセキュリティ面も安全
    • 従量課金
    • サーバーレス、可用性やサーバーの管理不要

(文字スライド多めだったのでキャプチャ割愛)

Ease of use

  • 簡単に使えます
    • ここではDynamoDB→ElasticSearchの例

1.作業の流れ

  • テーブル、View、Materialize view

f:id:fu3ak1:20201204163523p:plain

2.テーブルの作成(DynamoDB)

f:id:fu3ak1:20201204163643p:plain

3.テーブルのActivate

  • 最初はinactivateなので手動でActivateする
  • Activateを押すと、テーブル情報が見れる

f:id:fu3ak1:20201204163757p:plain

4.Viewの作成

  • SQLクエリを書いてViewを作成
  • Preview機能で事前に確認もできる

f:id:fu3ak1:20201204163842p:plain f:id:fu3ak1:20201204163915p:plain

5.マテリアライズドViewの作成

  • ターゲットのElasticSearchと名前を指定

f:id:fu3ak1:20201204163953p:plain

6.データのMapping

  • 自動的に推奨のタイプが表示される、手動変更も可能

f:id:fu3ak1:20201204164046p:plain

手順はここまで

Programmability and correctness (プログラムのしやすさと正しさ)

  • PartiQLの仕組みを使用して、さまざまなAWSデータサービスに接続ができる

f:id:fu3ak1:20201204164301p:plain

  • documentという形でデータ情報の定義ができる

f:id:fu3ak1:20201204164459p:plain

  • ここで最初の質問に戻り、どうやったらDynamoDBのデータをテキスト検索できるようになるか?
  • Elastic Views を使用

f:id:fu3ak1:20201204164654p:plain

  • Viewの作成例 *(細かなSQLの紹介がありつつ、)以下の要にCREATE VIEW文を使って変換が可能

f:id:fu3ak1:20201204164942p:plain

  • データの互換性、変換例(DynamoDB→Redshift)

f:id:fu3ak1:20201204165133p:plain

  • Mapping View
    • 値の変換も可能(色付のところ)

f:id:fu3ak1:20201204165414p:plain

  • DynamoDBのデータは柔軟性があるので、想定外のデータが入ることもある。(バイナリのような)
  • 例外データとしてS3などに別出しできる

f:id:fu3ak1:20201204165519p:plain

  • Violation Views
  • 例外データを抽出するためのView
  • この例では通常データはRedshift、例外をS3へ

f:id:fu3ak1:20201204165820p:plain

  • GUIで簡単にMapping、GUIはパワフル(見やすい)

f:id:fu3ak1:20201204170003p:plain

  • コードで書きたい場合はSQLを書き込むこともできる

f:id:fu3ak1:20201204170027p:plain

Re:cap

  • 2021年に向けてサポートするデータソースおよびターゲットの追加を多く予定している
  • フィードバックください!

感想

データのETL処理はこれまで、Glueで実現するならGlueジョブを用意して、パイプライン用意して、実行間隔などを決めてなど色々とやることがありました。 もちろんジョブコードの開発も必要。

ジョブ作成に関しては、GUIベースでよりわかりやすく開発ができるGlue Studioが今年?に発表されていました。 Glue Studioは、下記クラメソさんの記事がわかりやすいと思います。

dev.classmethod.jp

それに対しGlue Elastic Viewsでは、ジョブだけでなく処理実行の管理までマネージドになり、より利用者の開発範囲が小さくなった機能のように見えました。 全てのユースケースで使えるかはまだ微妙なところですが、マッチするのであれば積極的に使っていきたいですね。

まだプレビュー段階なのでわからないことは多いですが、一般公開されたらまた見ていきたいです。

re:Invent2020セッションレポート :(EMB008)AWS Proton: Automating infrastructure provisioning & code deployments

概要

2020 re:Inventで新たに登場した AWS Protonの紹介セッションです。 機能が多そうで、Keynoteだけでは中々中身まで理解するのが難しかったので本セッションを見ました。

アライさんがものすごくわかりやすい記事を書いてくれているので、それを見るだけでも理解が深まると思います。 こちらも是非。

iselegant.hatenablog.com

内容

課題点、背景

  • マイクロサービスの例
    • Developerは使いやすい、コードフォーカス

f:id:fu3ak1:20201203104633p:plain

  • 一見シンプルであるが、実はシンプルじゃない
    • マイクロサービスにするとコンポーネントが増える
    • Pipelineも必要、設定も環境ごとに必要
    • Monitoringの設定も必要

f:id:fu3ak1:20201203104746p:plain

  • インフラは標準化して管理しやすくしたい
  • Developer(開発チーム)は開発を早くして自動化したい
  • それぞれアップデートも必要

f:id:fu3ak1:20201203104932p:plain

f:id:fu3ak1:20201203105100p:plain

  • 集中管理(左側):一元管理になるが変更時が面倒。Developerから問合せを受けて検討、変更する等のフロー
  • 従来のPaas(右側):DeveloperはPaasにデプロイするので開発しやすい、一方でコンプライアンスやセキュリティが守られているか等の管理面で不安がある。
  • セルフ(In-house)管理(真ん中):集中管理とDeveloperの間が取れてGood!ただし、このカスタムソリューションを自分たちで管理していく必要がある。バージョン管理なども大変
  • そこでProtonの登場!!

f:id:fu3ak1:20201203105205p:plain

Protonとは

  • インフラ担当はインフラテンプレートをアップロード(パイプラインやモニタリングも)
  • アプリ担当はアプリケーションをデプロイ

f:id:fu3ak1:20201203105452p:plain

  • 主要な機能
    • セルフサービスなインフラおよびコード管理
    • インフラ管理をワンクリックで集中管理できる
    • サードパーティの組み込みも可能(TerraformやJenkinsやモニタリングツールも予定)

f:id:fu3ak1:20201203105521p:plain

  • Protonのビジョン
    • ベストプラクティスの適用や新機能の適用を助ける
    • クラウドネイティブでモダンな開発を可能にする
    • インフラ担当がビジネスにとってベストなアーキテクチャを決定できる

f:id:fu3ak1:20201203105636p:plain

  • Protonのコンセプト(Protonの主要なリソース)
    • Environment:VPCやClusterを管理、サービスで共有するインフラ部分
    • Services:ワークロードごとに設定、FaragateやLambdaなど

f:id:fu3ak1:20201203105827p:plain

「 Proton使用時の流れ 」

  1. インフラのテンプレートを定義(Environment、Service)
  2. テンプレートからリソースをCreate
  3. アプリがサービスを選んでデプロイ(青枠)

f:id:fu3ak1:20201203110020p:plain

  • Protonのアーキテクチャ
    • 2のservice(Fargate、Lambda)と1つのEnvironment
    • 環境はStagingとProduction2種類(今回の例では)
    • Pipelineを使用して、Staging→Productionで展開できる(パイプラインが環境間で連携されている)

f:id:fu3ak1:20201203110138p:plain

  • Protonに定義を登録することで標準化できる
  • 主にインフラ管理者向け

f:id:fu3ak1:20201203110209p:plain

  • Protonテンプレートの解剖(Anatomy)
    • インフラテンプレートを作成し、パラメータを決定。パラメータはDeveloperが変更できる値を設定
    • CI/CDをテンプレート作成、インフラと土曜
    • Protonのスキーマ化、Developerに必要な情報を整理、パラメータなど
    • マニフェストの設定、作成した情報の一元管理、確認(?、すいません英語よく聞き取れず自信ない)

f:id:fu3ak1:20201203110416p:plain

  • テンプレートの例
    • 左側が環境ごとにテンプレートを分けた例
    • 右側がProton、1つのテンプレートとSchemaを設定

f:id:fu3ak1:20201203110519p:plain

  • テンプレートができたらProtonの画面から登録

f:id:fu3ak1:20201203110631p:plain

  • 登録したテンプレートは画面上で管理できる

f:id:fu3ak1:20201203110705p:plain

  • サンプルテンプレートを多く公開しているので是非みてね!W-Aなテンプレートもあり

f:id:fu3ak1:20201203110735p:plain

  • テンプレートのバージョン管理
    • 変更したらバージョン管理を
    • マイナーとメジャーの2種類あり
      • マイナーはDeveloper(アプリ)に影響を与えないインフラのアップデート
      • メジャーはDeveloper(アプリ)に影響を与える構成変更のようなアップデート
  • 基本は最新を使うようにしましょう

f:id:fu3ak1:20201203110851p:plain

  • テンプレートのバージョン管理画面
    • 全バージョン詳細も見れる
    • 現在どのテンプレートが使われているのかもわかる

f:id:fu3ak1:20201203111216p:plain

  • Environmentsで定義しているもの
    • VPC、サブネット
    • パイプラインとその中のステージ
    • リソースプロビジョニングのためのIAMロール

f:id:fu3ak1:20201203111406p:plain

  • Developerはコードに集中
  • コードを書いたらサービスを指定してデプロイ
  • デプロイのサービスはマネージド化されて見える(?)

f:id:fu3ak1:20201203111528p:plain

  • 使用方法

1.サービステンプレートの選択

f:id:fu3ak1:20201203111647p:plain

2.パラメータの入力、パラメータ項目はParameter Schemaで管理されている

f:id:fu3ak1:20201203111844p:plain

3.サービスができたら画面上で確認できる

f:id:fu3ak1:20201203112011p:plain

4.詳細も確認できる、パイプラインの状況やアラートの状況も見れる

f:id:fu3ak1:20201203112043p:plain

まとめ

  • まだパブリックプレビュー、フィードバックください

    • 今はCloudFormationが基本
    • EnvironmentsとServiceのデプロイ、更新ができる
    • CodePipelineとも連携
  • Roadmap(今後)

    • モニタリング機能
    • サードパーティの機能追加
    • タグの自動付与
    • マルチアカウント対応
    • テンプレートアクセス=どのテンプレートに誰がアクセスできるかなどのアクセスコントロール

f:id:fu3ak1:20201203112440p:plain

  • 見てね!フィードバックもください(2回目)

f:id:fu3ak1:20201203112501p:plain

私の感想、まとめ

英語で聞きながら書いているので少し間違っているところがあるかもしれません。すいません。何かあればご指摘ください。 ただProtonのコンセプトや方向性はこれで理解できたかなと思います。

背景を知るのは大事ですね、Protonの目的は以下のように感じました。

  • インフラテンプレートの一元管理:色々なところで好き勝手に作るのではなく、ベストなものをProtonで集中管理。履歴管理もできる
  • インフラ、アプリ(Developer)の役割明確化:Developerはコードに集中できるように。作ったコードをProton経由でデプロイすれば標準な形式でデプロイできる
  • 各種リソースの状況管理:Protonを使用することで、どの環境でどのアプリ、テンプレートが使用されているのかわかるようになる

私の環境でもインフラテンプレートやパイプラインが多くなってきて、同様の課題を感じていたので、すばらしいサービスだと思います。 まだプレビュー段階なので、新機能にワクワクしながら実際の運用導入を検討したいと思います。

re:Invent2020セッションレポート :(ZDC301)The journey of an AWS CloudFormation template to AWS CDK

概要

「CloudFormationテンプレートをどのようにCDKに移行すれば良いか」というテーマで、実際の移行方法をコードのデモを活用しながら説明してくれるセッションです。

Agenda

  1. pipelineテンプレートの移行
  2. インフラ(今回セッションではECSリソース)のCDK組み込み
  3. CDKネイティブに変更
  4. CDKの利点を活用

デモで使用されるコードのサンプルはこちら

github.com

f:id:fu3ak1:20201201135838p:plain

Step1: migrate the Pipeline template

  • まずはCodePipelineのCloudFormationのテンプレートをCDKに移行しよう
  • インフラ側のCloudFormationのテンプレートはKeepしておく

Why:

  • ステートレスで本番サービスへのリスクも少ないので最初に移行しやすい
  • 並行して(複数のパイプライン)実行しやすい

(ここで実際のコードでデモ、元となるCloudFormationテンプレートと、Pipeline CDKコードの紹介)

f:id:fu3ak1:20201201140039p:plain

Step2: include infrastructure template

  • インフラテンプレート(ECSのCloudFormation)をCDKに組み込もう

    • こんな感じ(デモより)、CfnIncludeを使用してテンプレートを読み込む f:id:fu3ak1:20201201140844p:plain
  • 互換性チェックのため、テスト(パラメータチェックなど)も合わせて組み込もう

Why:

  • CDKネイティブなコードへの準備
  • CDK化してうまく活用できる点がいくつかある
    • パラメータをPipelineから取得してCDK経由で渡す、テストの追加、マルチアカウントなど

(ここで実際のコードでデモ)

f:id:fu3ak1:20201201140424p:plain

Step3: turn into native CDK app

  • パラメータを(CloudFormation)テンプレートから抽出してCDKに組み込もう
    • 一気にやるのではなく徐々に、複雑さに応じて
  • CDK assetsを使用してPipelineをシンプルにしよう
    • Docker imageはAssetとしてファイル経由で取得

Why:

  • aws-ecs-patternを使用して、ECSの様々なユースケースに対応できる
  • CDKを使用したDocker imageのビルド、ECRへのpushができる
  • 書くコードも少なく済む

(ここで実際のコードでデモ)

f:id:fu3ak1:20201201141101p:plain

Step4: take advantage of CDK

  • autoscalingを追加しよう
    • ここではECSサービスのAutoScaleをデモで実施
  • アラームwith cdk-watchful(サードパーティな監視ライブラリ)を追加しよう
    • CPUやメモリ、ALBへのリクエスト数のメトリクス監視、アラームを自動設定してくれる
    • CloudWatchダッシュボードも追加してくれる
  • その他色々好きなものを追加しよう

Why:

  • CDKパワーを活用してリソース(構成)の再利用に役立てる

(ここで実際のコードでデモ)

f:id:fu3ak1:20201201141548p:plain

Our Migration Toolbox (まとめ的な)

  • クラッチなコードを書き直そう
    • PipeLineが良い例なので是非お試しを
  • "ハイブリッド"スタック
    • CloudFormationテンプレートをCDKにそのまま組み込むことでハイブリッドなスタックも可能
    • 徐々に(step by step)でCDKネイティブに移行していく
  • ステートフルなリソースをKeepしておく
    • データベースやS3など、Statefulなリソースは注意、リソース本体は残しておいて、論理IDの置き換えで対応できるように
  • ハイレベルな構成でCDKを活用しよう
    • CDKを使いこなすと、CDKライブラリやサードパーティのライブラリをうまく活用できる

f:id:fu3ak1:20201201142312p:plain

感想

私はCDK初心者で、今もCloudFormationで頑張って運用しているプロジェクトばかりです。そしてECSも多くのプロジェクトで使用しています。CloudFormationはAWS標準でわかりやすく書けて良いのですが、運用を考えるとちょっと無理して書かなきゃいけないところもあり、CDKもありかなぁと考えているところでした。

本番サービスに影響のないCodePipelineからの移行がおススメということで、サンプルコードを真似しながら試していこうかと思います。

Docker Hub の Rate Limitに引っかかったのでdocker loginで対策した

AWSのcodebuildで、docker buildが失敗するようになりその対応をしたので備忘録です。

Docker Hub の Rate Limitとは

英語になりますがこちらに記載があります。

www.docker.com

The rate limits will be progressively lowered to a final state of 100 container image requests per six hours for anonymous usage, and 200 container image requests per six hours for free Docker accounts. Image requests exceeding these limits will be denied until the six hour window elapses.

ざっくり私の翻訳

rate limits を徐々に低くしていって、最終的には匿名ユーザーは100 image リクエスト/6時間、free Dockerユーザーには200 image リクエスト/6時間にするから!それ超えたら6時間拒否するからね!

ちなみに現状では以下のlimitとなっているようです。

f:id:fu3ak1:20201120235605p:plain

これを見た私の感想は、「フーン、まぁそんなにたくさんimage リクエストなんてしないし大丈夫だろ、うちはそんなたくさんCICDする組織じゃないし( ̄σ・ ̄*)」という感じでした。

エラーに遭遇、原因判明

そんな気持ちのままAWSのCodeBuild(CodePipeline経由)でdocker buildを行っていると、以下のエラーが・・

toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit

!?まだ5回くらいしかbuildしていないのに?

少し考えて原因がわかりました。

匿名ユーザーのリクエストのカウントがIPアドレス単位なので、CodeBuildのIPアドレスでカウントされるということでした。

勝手に頭の中で以下のようにユーザー単位でカウントされると思い込んでしまっていたのですが、、

f:id:fu3ak1:20201121000423p:plain

実際は以下のようなイメージですね。IPを共有するので、初めてdocker buildを行う場合でもほかのユーザーの影響を受けてエラーになる可能性があります。

※実際はCodeBuildのIPアドレスは複数ありますが、共有するというイメージで1つで書いています。

f:id:fu3ak1:20201122104635p:plain

対策

対策は以下のようにいくつか考えられます。

  • ECRに定期的にイメージをコピーしておく。
  • CodeBuildをVPC内で実行させ、共用ではなくElastic IPなど固定のIPアドレス経由でDocker Hubにアクセスする
  • Docker Hubユーザーを作成してログイン処理を行う

今回は手間が一番かからなそうなログイン処理を実装することにしました。手順をまとめておきます。

Docker Hub ユーザーの作成

Free Planでユーザーを作成します。メールアドレスが必要です。

Docker Hubのページから、Sign Upします。

f:id:fu3ak1:20201121001631p:plain

画面の指示に従っていけばユーザーの作成が完了します。

作成、ログイン後、アクセストークンを発行します。パスワードでログイン処理も可能なのですが、トークンのほうが無効化できたり、プロジェクトごとで分けれるといった利点があるため今回はトークンにしました。

右上のユーザー名>Account Settingsを選択

f:id:fu3ak1:20201121002300p:plain

左側のメニューからSecurityを選択し、右側のNew Access Tokenをクリックします。

f:id:fu3ak1:20201121002529p:plain

Descriptionが必須のため、任意の文字を入力してCreateします。

f:id:fu3ak1:20201121002658p:plain

Tokenが表示されるのでコピーしておきます。Closeするともう表示できなくなるため注意です。

f:id:fu3ak1:20201121002923p:plain

SSM Parameter Storeへログイン情報格納

ログイン情報を作成できたので、AWS側で使用します。Codebuildで使用するbuildspec.ymlにログイン情報を直接記載するのはセキュリティ的によろしくないので、Systems ManagerのParameter Storeを使用します。 他にはSecrets Managerという選択肢もあるのですが、今回はローテーションを考慮しないかつ無料であるParameter Storeを使用します。

AWS Systems Manager>パラメータストア>パラメータを作成の順で選択します。

まずはdockerhub-userを作成します。(名前は任意でOKです)

f:id:fu3ak1:20201122102504p:plain

情報を秘匿化したいため、安全な文字列を選択します。暗号化に使用するキーの指定が必要ですが、今回はAWS管理のデフォルトのものを使用します。

f:id:fu3ak1:20201122100131p:plain

値にユーザー名を入力して作成します。

f:id:fu3ak1:20201122100451p:plain

dockerhub-tokenも同じように作成します。

f:id:fu3ak1:20201122102626p:plain

buildspec.ymlの修正

ログイン情報が格納できたので、buildspecに記載しているdocker buildの部分を修正します。

※Codebuildの仕様はこちらを参考にしてください。

以下のように、envのところにparameter-storeのところに作成したパラメータストアのKey名を書いておきます。

env:
  parameter-store:
    DOCKER_USER: dockerhub-user
    DOCKER_TOKEN: dockerhub-token

pre_buildフェーズのところで、ecrのみログインしていたところを、dockerhubにもログインするよう追記します。

「echo $DOCKER_TOKEN・・」の行です。パスワードとユーザー名は先ほどenvに記載したパラメータストアから取得しています。

  pre_build:
    commands:
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
      - echo $DOCKER_TOKEN | docker login -u $DOCKER_USER --password-stdin

CodeBuildを実行してログを見てみると、以下の通りログインに成功していることが見れます。

[Container] 2020/11/20 14:34:30 Running command echo $DOCKER_TOKEN | docker login -u $DOCKER_USER --password-stdin
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

[Container] 2020/11/20 14:34:32 Phase complete: PRE_BUILD State: SUCCEEDED

ログは割愛しますがdocker buildも無事成功しています。

これで作成したユーザーで200回/6時間まではlimitに引っかからないでしょう。

まとめ、感想

同じように失敗して困った方、なにかの参考になれば幸いです。

200回/6時間の制限はこの対策を行った後もあるため、多くのdocker buildを行う方は注意が必要ですね。

また今後は別の対策として、AWSのECRのパブリック化するようなので、今後はそちらも活用できるかもしれません。

aws.amazon.com

待望!Session Managerのリアルタイムログ配信機能

万歳!素晴らしいアップデートが出ました!

aws.amazon.com

Session Managerとは

AWSにはSystems Managerという、EC2を管理するサービスがあり、その中の1つの機能としてSession Managerがあります。 Session Managerを使用して、EC2やオンプレミスのサーバへのSSHやRDPで接続できます。

詳細や始め方は過去の記事にも書いていますのでそちらも良ければ見てみてください。

fu3ak1.hatenablog.com

fu3ak1.hatenablog.com

今回のアップデートについて

Session Managerには操作ログをS3またはCloudWatch Logsに転送するという便利な機能があるのですが、これまでは操作終了時にログを転送するという仕様でした。

(ログ保存機能の私の過去記事より)

1点注意なのは、ログ転送はリアルタイムではないという点です。 セッション終了時にログを転送する仕組みとなっているため、shutdownコマンドでOS停止したり、ブラウザを閉じて終了した場合は、ログは転送されません。

これがリアルタイム(操作中に転送)になりました!現在はCloudWatch Logsのみ対応のようです。

リアルタイムになったことで、強制的なログ取得、またログ監視をして不正操作時にセッション強制中断など、よりセキュアなログイン管理ができそうです。

試してみる

では実際に試してみます。Session Managerの基本的な使いかたは過去記事に書いていますのでここでは割愛します。

ログ転送の設定

Systems Manager>Session Manager>設定の順で、設定画面に遷移します。

CloudWatch loggingのところをEnableにすると、「Stream session logs (Recommended)」という項目が!こちらを選択し(デフォルト)、任意のCloudWatch ロググループを選択します。

※ロググループは事前作成が必要です。暗号化を有効にする場合はKMSキーを作成してロググループを暗号化しておく必要があります。

f:id:fu3ak1:20201119094627p:plain

上記のとおり設定したら保存します。

EC2へのアクセス

Session Managerでアクセスしてみます。接続までの画面遷移方法は色々あるのですが、私は最近ではEC2の画面から接続>セッションマネージャーで使用することが多いです。

f:id:fu3ak1:20201119100233p:plain

が、失敗。。初期状態では、SSM Agentのバージョンが低いようで接続できないようです。

f:id:fu3ak1:20201119095437p:plain

SSM AgentのバージョンUP

接続できないのでバージョンUPします。Systems Manager経由のバージョンUPが楽なのでそれを使用します。

Systems Manager>Run CommandでRun Command画面へ遷移し、コマンドドキュメントとして「AWS-UpdateSSMAgent」を使用します。(SSMで検索すればOK)

f:id:fu3ak1:20201119100734p:plain

パラメータはデフォルトでOKです。最新にバージョンアップされます。

f:id:fu3ak1:20201119100858p:plain

バージョンUPしたいインスタンスを手動で選択します。

f:id:fu3ak1:20201119101040p:plain

その他はデフォルトで、最下部の実行を押します。すると以下のように正常終了するはずです。

f:id:fu3ak1:20201119101153p:plain

EC2へのアクセス(リトライ)

もう一度接続します。

f:id:fu3ak1:20201119100233p:plain

接続できました!!

f:id:fu3ak1:20201119101300p:plain

試しに以下のようにコマンドを実行してみます。

$ bash
$ date
$ pwd

f:id:fu3ak1:20201119100300p:plain

そのままセッションを終了せずに CloudWatchログを見てみます。

ありますね!! CloudWatchログの画面をそのまま見るとわかりにくいですが、確かに実行したコマンド(bash、date、pwd)が確認できます。

f:id:fu3ak1:20201119101546p:plain

実運用になった場合は、CloudWatch Logs Insightsや、Elasticsearchに送るなど、可視化の工夫が必要です。

まとめ、感想

すばらしい機能です。Security Groupの許可不要で、ログも強制的に取得可能となった今、監査要件の高い本番環境でも使用できるのではないでしょうか。

私としても、今後はSSHアクセスではなくSession Managerで運用できないか考えていきたいと思います。