CodeGuruにコードレビューされてみたらBoto3の便利機能Waitersを知った話

いつか使ってみようと思ってたCodeGuruを使う機会があり、Boto3にそんな機能あるのね、となった話です。
2021.04.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。AWS事業本部のKyoです。

スクリプト、便利ですよね。私も先日「CloudFrontのオリジンを別のものへ変更する」というPythonスクリプトを書いていました。主要な部分は、以下のような形です。

update_distributionはアップデートのリクエストになるので、レスポンスが返ってきた後、各エッジロケーションにアップデートされた設定がデプロイされるのを数分程度待つ必要があります。ここを待たずにInvalidationを行うとアップデート前の情報が再びキャッシュされる可能性があります。

そんなわけで以下のような実装になりました(簡略化しています)。

client = boto3.client('cloudfront')

# CloudFront distributionのアップデートリクエスト
response = client.update_distribution(
         DistributionConfig=distribution_config,
         IfMatch=etag,
         Id=distribution_id
     )

# エッジにアップデートされた設定がデプロイされるのを待つ
response = client.get_distribution(Id=distribution_id)
     while(response['Distribution']['Status'] != 'Deployed'):
         print('waiting for update distribution status...')
         time.sleep(10)
         response = client.get_distribution(Id=distribution_id)

# Invalidationの処理
...

待機の部分、whileで待ち受けるのはなんだかイケてないなぁ...と思いつつ、ぱっといいアイデアも出ずモヤモヤしていたところ、CodeGuruの存在を思い出しました。そういえばPythonにも対応していましたね。

やってみた

CodeGuruの利用方法は下記のエントリをご覧ください。

今回は思いつきだったので、CodeCommitに雑なレポジトリを作成、コードを格納、CodeGuru Reviewerを利用してみました。得られたのは以下です。

推奨事項として以下2点が得られました。

  1. 例外処理をちゃんとやりなさい(Exceptionを投げっぱなしでした)
  2. ループでの待機の変わりにWaiters(後述)という機能を使うといい

1.は言葉通りなので素直に対応するとして、2.は初めて知る機能でした。DevIOを探しても、boto3での例はあまり多くありませんでした(AWS CLIではそこそこ使われてるみたいです)。

あまり多くはない、と言いつつも以下のエントリがいい感じにWaitersを解説してくれていました。

詳しい使い方や説明はそちらに譲りますが、Waitersを利用すると任意のAWSリソースが特定の状態になるまでポーリングしながら待機することができます。また、ポーリングの回数や間隔などの変更も可能です。まさに今回のようなシチュエーションのためにある機能でした。

ということで、指摘を反映したのが以下になります。

max_attemptsdelayではWaitersのポーリング回数と間隔を指定しています。

これによって、上のwhile文を置き換えることができました。

client = boto3.client('cloudfront')

# CloudFront distributionのアップデートリクエスト
response = client.update_distribution(
         DistributionConfig=distribution_config,
         IfMatch=etag,
         Id=distribution_id
     )

# Waitersでデプロイ完了を待つ
    waiter = client.get_waiter('distribution_deployed')
    waiter.config.delay=delay
    waiter.config.max_attempts=max_attempts
    waiter.wait(Id=distribution_id)

# Invalidationの処理
...

修正を入れて、もう一度レビューをうけると推奨事項0、との結果が返ってきました。やったね。

所感

AWS SDKであるBoto3についてだから、という理由はあるかもしれませんが、CodeGuruのレビューによって知らなかった便利機能を知ることできたのは収穫だったと思います。スクリプト自体も長いものではありませんでしたが、2つ指摘をもらったので、コードを書いた際には一度CodeGuruにみてもらうと何かの発見につながるかもしれません。

最近CodeGuru Reviewerの料金体系が変わったので変更されたので、ご利用前にはぜひこちらもご覧ください。

以上、何かのお役に立てれば幸いです。