vCPUの上限をチェックするLambdaを作成しました

はじめに

先日、EC2の上限管理方法が各インスタンスタイプの個数ではなく、インスタンスファミリーごとの合計vCPU数となりました。
rioner2525.hatenablog.com
今回はこちらのアップデートに対応するため、vCPUの上限をチェックするLambdaを作りました。

チェック方法①

普通のチェック方法はCloudWatch Alarmを用いてvCPUの閾値に達したらメールを出すといった方法になるかと思います。
アラームの作成は各クォータから簡単に作成できます。
f:id:rioner2525:20191024103555j:plain
作成したアラームにSNSトピックを紐づけるだけで、閾値になったらメール通知するといったチェック方法が簡単に実装できます。
ただし、実際に上限を引き上げた場合はアラームの閾値を手動で変更しなおす必要があるので注意してください。
この方法は多分ベストプラクティスというか、AWSさんが想定しているであろうチェック方法ですね。

チェック方法②

他にもLambdaでチェックする方法があるかなと思い、今回作成したのでコード紹介します。
わざわざLambdaでチェックする意味はあるのか...と考えましたが、とりあえず以下に羅列しておきます。

  • チェックするためのリソースが1つのLambdaで完結できる。
  • ロールを引き受けて複数アカウントを横断してチェックすることも可能。
  • メールやslackなど通知方法や通知内容が柔軟に対応可能。

コード

コードの置き場所はここです。
vCPU-Limit/lambda_function.py at master · rioner/vCPU-Limit · GitHub

軽い解説

やっていることは以下。

  • 1週間のうち最大値のメトリクスを取得する。
  • 現在の制限値と比較する。
  • 上記を各インスタンスファミリーに対して実行する。
  • 閾値を超えていたものがあったら通知する。

今回は1週間のメトリクスで考えました。
運用の想定としては1週間のメトリクスを見て、慢性的にEC2が起動されてきてるなーとなったら上限緩和申請を出す。スパイクで一瞬だけ閾値を超えるぐらいならスルーするといった感じです。
なので、このLambdaを1週間ごとに起動するCloudWatch Ruleに紐づけます。

20~29行目あたり、1時間間隔のメトリクスを取得していますが間隔はなんでもよいです。最大値を取りたいだけなので。
76行目など、関数を読んでいる箇所。引数に 'quotacode' と入れていますが、これは各クォータの実際のクォータコードを入力してください。
f:id:rioner2525:20191024114331j:plain
このクォータコードはリージョンごと?などでアカウントが違っても同じ文字列だと思っていますがビビって公開してません(;^ω^)
その他は特に難しいコードなどもないので問題ないかと思います。
何かしら読者の皆様の参考になれば幸いです。
メール本文は以下のような感じになります。

Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances  
現在の制限値:xxxx  
過去1週間の最大値:xx  
上限緩和の検討しましょう。  
CloudWatchメトリクスのURLは以下となります。  
https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#metricsV2:graph=~(metrics~(~(~'AWS*2fUsage~'ResourceCount~'Resource~'vCPU~'Service~'EC2~'Type~'Resource~'Class~'Standard*2fOnDemand))~period~300~stat~'Maximum~view~'timeSeries~stacked~false~title~'Running*20On-Demand*20Standard*20*28A*2c*20C*2c*20D*2c*20H*2c*20I*2c*20M*2c*20R*2c*20T*2c*20Z*29*20instances~region~'ap-northeast-1~start~'2019-10-17T03*3a00*3a00.999Z~end~'2019-10-24T02*3a59*3a59.000Z)  

さいごに

サービスクォータのboto3を使ったLambdaをはじめて作成しましたが、制限値はぱっと取れるのですが現在値はぱっと取れないのですね...。
サービスクォータが取ってきているであろうメトリクスの情報が取れますので、今回は現在値については1週間のメトリクスから取ってくる方向にいたしました。
あと、1週間のメトリクスの推移を見るためにURL付けましたがほぼ直打ちなのでアップデートあったら修正が必要です(:3 」∠ )_

(追記2019/11/05)
そういえばインスタンスごとの制限値出てたよな...と思って TrustedAdvisor を見てみたら vCPU の合計数の値が表示されていました...
メトリクスから取ってくる~とか言ってた努力は一体...
ただ TrustedAdvisor ではよく使われる Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances だけっぽい?雰囲気なので一応意味はあったと思っておきます!

日経 xTECH EXPO 2019に展示側で参加しました

日経 xTECH EXPO 2019

日経 xTECH EXPO 2019が10月9~11日で開催されており、私は展示側で参加しておりました。
役割としては自社開発サービスの説明担当といったところです。
こういった技術展示会に展示側で参加するのは初めてだったので刺激になりました。
f:id:rioner2525:20191016205713j:plain

展示ブース

私の役割的には説明担当だったのですが、弊社ではコンパニオンの方をオファーしなかったので客引きも行いました。
ずっと立ち続けてサービス資料を胸の高さに持ち上げて笑顔でいる...なかなか大変なことでした。
私は合間に休憩時間をいただけていたので何とかなりましたが、周りのブースのコンパニオンのお姉さんたちはずっと笑顔で半端ないな!と思いました。
やはり普段ずっとクーラーの効いた部屋で椅子に座ってるタイプのオタクでは何も為しえないんだなとなりました(;^ω^)
説明自体は最初はうまくできなかったりもしたのですが、3日目にはうまくなってるねとチームの方に言われました(`・ω・´)キリッ
初めての方に理解しやすい言葉で説明する力はどんな環境でも役に立つと思いますので、今回普段経験できないことをやれてよかったと思います。

メインシアター

メインシアターではセミナーの合間にバーチャル記者の黒須もあさんの動画が流れていました。
f:id:rioner2525:20191016212253j:plain


かわいいですね!
なんというか、日経BPさんのようなちょっとお堅い企業さんでもこういった取り組みをされていることが素晴らしいと思いました。
歴史のある会社さんだと企画を通すのが大変なのではないかと邪推してしまいますが、目新しいことを率先して試していけるような体制に惹かれます。

おわりに

普段ならブースの方たちからすごい勢いで資料を渡されると思いますが、展示側のパスを持っているとしら~っとなるので回りやすくてよかったです('ω')ノ
あとはイベント会場でいろんなブースで渡されたであろう資料をバサッーとゴミ箱に入れている人を見てちょっと悲しくなりました...
自分も参加側だと特に気にせずいらない資料を捨てたりしてましたが、今後はせめてイベント会場では捨てないようにしようと心に決めました。

New Amazon EC2 On-Demand Instance limits now available ってメールが来たよ

はじめに

表題のメールがAWSから来ました。
何やらEC2オンデマンドインスタンスの制限にアップデートがくるらしい。
アップデートブログは以下。
Amazon EC2 で vCPU ベースのオンデマンドインスタンス制限が利用可能に
ドキュメントは以下。
オンデマンドインスタンス - Amazon Elastic Compute Cloud

ちょっと読んだ

(_ *˘ω˘)_ドレドレ...
どうやらEC2インスタンスの制限の数え方がインスタンス数じゃなくてvCPU数に変更になるらしい。
EC2インスタンス数の制限監視とかしてましたが合わせてアップデートしないといけないですねこれは...。
それっぽい情報まとめときます(。゚ω゚)

それっぽい情報まとめ

ドキュメントの通りなので、そっちも確認ヨロデス(゚д゚)ノ

従来のEC2インスタンス制限

インスタンスタイプ デフォルトの制限値(インスタンス数)
m5.large 20
c5.large 20
p3.2xlarge 1
h1.8xlarge 10
... ...

これから

インスタンスファミリー デフォルトの制限値(vCPU数)
A, C, D, H, I, M, R, T, Z 1152 vCPUs
F 128 vCPUs
G 128 vCPUs
P 128 vCPUs
X 128 vCPUs

アップデートスケジュール
2019/9/24 ~ vCPUベースの制限をオプトイン可能
2019/10/24 ~ すべてのアカウントがvCPUベースの制限に切り替え

オプトインしてみる

①EC2 ダッシュボードの 制限 にオプトイン用のボタンあり。
 設定してから15分くらいかかるらしい。
f:id:rioner2525:20190926184851j:plain

AWS Service Quotas を見てみる。
 ワァオー。vCPU数制限になってますねぇ!
 デフォルトのクォータ値がちょっと違う?気もしますが....問題なくAPIでも現在のvCPU制限値が取れそうですね。 f:id:rioner2525:20190926191717j:plain

③オプトインがあった場所にオプトアウト用のボタンがあるのでオプトアウト。
 これも15分くらいかかるらしい。

さいごに

今回のアップデートでEC2インスタンス数の制限監視等をしていた組織は合わせてアップデートの必要がありそうです。
アップデート内容についてはインスタンスファミリーごとの制限になったことで、以前のインスタンスタイプごとの制限より分かりやすく簡便になったと思います!
AWS Service Quotas を使った制限監視に切り替えていくいい機会と前向きに捉えて作業しませう(;'∀')

(2019/10/24 更新)
AWS Service Quotas を使った制限監視の記事を挙げました。
rioner2525.hatenablog.com

ドコモさんのAWS運用ノウハウ紹介講演に行ってきたよ

はじめに

こちらの講演に行ってきました。
【NTTドコモ×AWS】徹底公開!ドコモのクラウド運用ノウハウ!! - connpass
せっかくなので感想メモを書いておきます。
問題なさそうなところだけ書こうと思いますが、もしも公開やめろと言われたら消します(;'∀')

"Well-Architected Framework"活用方法のご紹介

AWS クラウドサービス活用資料の内容とほぼ同じ。
https://d1.awsstatic.com/webinars/jp/pdf/services/20181211_AWS-BlackBelt-Well-Architected.pdf
クラウドの利用方法について統制を効かせるチームがないまま自由に使うのは非常に危険です。(特にセキュリティ面と無駄なコスト)
そういう場合はWell-Architected Frameworkを利用してセキュリティリスクなどのチェックをすることはとても大切だと思います。
あと、この資料の中にあるレビューの進め方は普段のレビューでも意識したい大切なことが書かれているなぁと感じます。
①レビューでは「誰も責めない」。監査ではなく話し合い。
②変更が困難な状況にならないように設計の初期段階のレビューを心がける。
③すべての関係者がレビューに参加できるように手配する。
④本番運用後も継続的にアーキテクチャをレビューする。
→新しいAWSサービスの機能が追加されてもっと効率的な設計が可能になることはままある。
 新しいEC2インスタンスタイプが出て、そっちの方がコストが効率的とか。

ドコモのCCoEの取り組みについて

ドコモさんのCCoEチームではクラウドを利用していて発生する以下の課題を解決することを目的としているらしい。

  • 内部統制
    社内基準を満たすようにクラウドでのポリシーを策定して浸透させる。
  • リテラシー向上
    初心者がクラウドで失敗しないように教育する。
  • アカウント管理
    管理者不明のアカウントがないように社内アカウントの一元管理。
  • コスト管理
    支払いの統一やコストを可視化して分かりやすくする。

具体的にやっていることは以下とか。

  • クラウド環境利用のためのガイドライン作成。
    AWSの考え方やお作法から構成・セキュリティの指針まで記載。
  • 自社セキュリティ基準に違反したものを検知、防止。
  • 社内AWSアカウントの取りまとめ
    請求書の支払いを取りまとめて、アカウント自体の管理はサービスの担当者に任せる。

あとはAWSの新機能を検証して事業部門のコンサルなどもやるらしい。
CCoEチームがAWSの機能を触って知識を持っていることが社内のクラウド導入を促進するポイント。

ちなみに500以上のアカウントでCCoEチームは10人程度らしい...。
すごい...きっと激務に違いない(-"-)

その他

あとの講演は自社サービスの宣伝でしたので省略。
ただ、セキュリティ統制のお話は面白かったので以下メモ。

セキュリティ対策の落とし穴
  • セキュリティ審査を必須とすると、審査を通す事が目的化される。
    審査はベースラインでサービスの特徴に応じた追加対策が必要。
  • マネージドポリシーのFull権限やReadOnly権限を多用してしまう。(その場しのぎ)
    ReadOnly権限にはGETも可能なポリシーもある。権限の管理やデータ暗号化なども考える必要あり。
  • 通信路のセキュリティ対策ばかり考慮してしまう。(セキュリティ対策の偏り)
    内部犯行の考慮も必要。セキュリティは全レイヤで考える必要あり。
トレードオフ
  • 「セキュリティ」は「コストや利便性」とのトレードオフ
  • 「統制」は「アジリティやフレキシビリティ」とのトレードオフ
  • ドコモさんではクラウドのアジリティ、フレキシビリティを最大限に活かし、ビジネスのブロッカーとならないようにゲートキーパーではなくガードレールの考え方。
「自動化」と「可視化」の重要性
  • ガードレールに収まっているかの検知は自動化する必要あり。
  • ガードレールに収まっていないリソースを可視化してサービス担当者に自律的に意思決定、リスクテイクさせる。
    →サービス担当者のクラウドリテラシーの向上も兼ねている。
  • 「自動化」と「可視化」がなければガードレールを強く狭くするほかなく、CCoEチームがクラウド利用のブロッカーとなってしまう。

おわりに

大変勉強になりました。ありがとうございます。
ドコモさんのような長い間AWSを利用している会社が自社内の取り組みやノウハウを公開されるというのは、後進のものからすると非常に参考になりますね。
運用部分は一度決めてしまうとなかなか変えづらい部分もあるかと思いますので、自社内の部門を横断して慎重に方針を決める必要があるなと再認識いたしました。

AWS Python(Boto3) の例外処理について ClientError の場合の具体例

はじめに

前回書いたBoto3の例外処理を行う方法の記事を見返したら、だいぶ分かりづらいな...と思ったので本記事で ClientError の場合の具体例を記載しようと思います。
rioner2525.hatenablog.com

具体例

仮定

・S3バケット内のテキストファイル ( test.txt ) を Lambda で取得して、ファイルの内容を Lambda 内で更新してアップロードする。
・テキストファイルが存在しない場合は新規作成とする。

こういった仮定の場合はバケット内にテキストファイルが存在しているかチェックするより、直接取得することを試みてエラーが発生した場合に判断する方が可読性が高く処理速度も速いコードになると思います。
そのことを鑑みて具体例のコードは以下。

コード

コードの置き場所はここです。
boto3_error/lambda_function.py at master · rioner/boto3_error · GitHub

軽い解説

ClientError の場合は botocore.exceptions.ClientError でエラーをキャッチできます。
e.response['Error']['Code'] って何だよと思われるかもですが、こちらは公開されている botocore リポジトリの exceptions.py を見ていただければ分かるかもです。(389 ~ 415 行目)
https://github.com/boto/botocore/blob/develop/botocore/exceptions.py
例えば上記コード内のテキストファイルが存在しないパターンのエラー内容は以下のようになります。

print(e)
print(e.response['Error']['Code'])
print(e.response['Error']['Message'])
print(e.operation_name)

↓ 結果

An error occurred (404) when calling the HeadObject operation: Not Found
404
Not Found
HeadObject

というわけで実際に想定しているエラーを発生させてエラー内容を見て、except 内で条件分岐を行えばよいと思います。
例えば Lambda にアタッチされた実行ロールに S3 バケットへのアップロード権限が足りない場合のエラー文は An error occurred (AccessDenied) when calling the PutObject operation: Access Denied だったりするので、この場合は以下のように s3.meta.client.upload_file 関数部分にtry-except文でキャッチできると思います。

e.response['Error']['Code'] == 'AccessDenied':
    print('権限足りない')
    raise Exception(e)

以上です。
ClientError 以外のエラー内容まで分岐させる場合は前回の記事を参考に botocore リポジトリのエラー関連のプログラムを確認してください。