kakakakakku blog

Weekly Tech Blog: Keep on Learning!

CloudFormation の IaC ジェネレーター機能をサクッと試せる「IaC Generator Workshop」

2024年2月にリリースされた AWS CloudFormation の「IaC ジェネレーター機能」を使うとマネジメントコンソール・AWS CLI などを使って作った(作ってしまった)リソースをスキャンして,自動的に AWS CloudFormation テンプレート化 (YAML / JSON) できる❗️もちろんそのまま AWS CloudFormation スタックにリソースをインポートすることもできる.

aws.amazon.com

今までも AWS CloudFormation のインポート機能はあったけど,リソース設定と見比べながら(そしてドリフト機能を活用しながら)テンプレートを書くのはそこそこ大変さがあったと思う.IaC ジェネレーター機能を使う流れは以下のブログにも載っていて,今回紹介するワークショップの内容にも似ている👀

aws.amazon.com

IaC Generator Workshop

この IaC ジェネレーター機能をサクッと試せるワークショップ「IaC Generator Workshop」も公開されていて,試してみた💡

実は2024年2月にワークショップも公開されていて,すぐに試そうと思ったけど,環境セットアップで使うスクリプト infrastructure-script.sh にアクセスすると Access Denied になってしまっていて進めなかった.1ヶ月ほど定期的に確認しても直ってなくて諦めていたけど,最近確認したら修正されていたので,改めてワークショップの内容を確認しておくことにした.

catalog.workshops.aws

ワークショップの内容としては,Amazon VPC 関連リソースと Amazon EC2 インスタンスをスクリプト (AWS CLI) で作って,リソースを AWS CloudFormation の「IaC ジェネレーター機能」でテンプレート化する.以下はスクリプトを実行したときに出力されたリソース情報一覧(既に削除済).

These are the resources created, you will need these ids later in the workshop.
Key Pair:  iacgenerator
VPC ID: vpc-00e0e3957e53ef021
Subnet ID: subnet-05a5cc381ac3dcce6
Internet Gateway ID: igw-0e98de8f97252af56
Route Table ID: rtb-0cff1f90fa8f83671
Security Group ID: sg-0c5db16219d23efd4
Instance ID: i-0c543696db799acf8

そして IaC ジェネレーター機能では,選択したリソースに関連するリソースも自動的に含めることができる.今回のワークショップだと AWS::EC2::NetworkAclAWS::EC2::SubnetNetworkAclAssociation などは「関連リソース」に含まれていた.

IaC Generator Workshop: テンプレート化

ちなみにテンプレート化したときに「リソース警告」も出ていた.AWS::EC2::InstanceAWS::EC2::Subnet など IaC ジェネレーター機能でサポートしてるリソースでもプロパティレベルでサポート対象外になっていることもありそうだった.このあたりは影響が出るかどうか確認しつつ,必要ならテンプレートを編集してからインポートすることもできる👌

docs.aws.amazon.com

IaC Generator Workshop: リソース警告

そして,最後はテンプレートをそのまま AWS CloudFormation スタックにインポートする.ちなみに今回のワークショップではテンプレート化するときに DeletionPolicy: Delete を指定するようになっているため,ワークショップ終了後のお掃除はインポートしたスタックを削除すれば良いという流れになっていた(ちなみに僕の環境だと一部の VPC リソースが削除失敗になってしまった💨).

IaC Generator Workshop: リソースをインポート

まとめ

もしまだ AWS CloudFormation の IaC ジェネレーター機能を試してなくて気になっていれば,1時間以内でサクッと終わるワークショップ「IaC Generator Workshop」がおすすめ❗️

関連ドキュメント

docs.aws.amazon.com

GitHub Actions でワークフローの同時実行を防ぐ concurrency 設定

GitHub Actions ではデフォルトの挙動として同じワークフローの複数のジョブを同時実行できる.無駄に待つ必要がないという意味ではメリットがあるけど,ワークフローによっては同時実行したくないこともあると思う.

GitHub Actions でワークフローが複数トリガーされてしまって慌てて止めたという経験もあったりする😅例えばワークフローの実行時間が長く,完了する前に次のコミットをプッシュしてしまったり,ワークフローの実行が完了する前にプルリクエストをマージしてしまったり💨

concurrency 設定

GitHub Actions ではコンカレンシー (concurrency) という設定があって,ワークフローの同時実行を制御できる.今回はワークフローレベルで試すけど,ジョブレベルで細かく制御することもできる❗️個人的にはとりあえず設定しておいても良さそうかなと思う.

docs.github.com

concurrency サンプル1(待機)

以下の例では GitHub ドキュメントを参考に concurrency.group${{ github.workflow }}-${{ github.ref }} を設定したため concurrency-refs/pull/1/merge のような名前になり「プルリクエストレベルで」同時実行を制御することになる💡そして concurrency.cancel-in-progressfalse を設定しているため,後続のトリガーはキャンセルにならず実行待機になってから実行される🛑

name: concurrency

on:
  workflow_dispatch:
  push:
    branches:
      - develop
  pull_request:
    branches:
      - develop

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: false

jobs:
  sleep:
    runs-on: ubuntu-latest
    steps:
      - name: Sleep
        run: sleep 60

concurrency サンプル2(キャンセル)

concurrency.cancel-in-progresstrue を設定すると,実行中のワークフローをキャンセルして最新のワークフローを実行できる🙆‍♂ 例えばデプロイ関連のワークフローであれば最終的に後に実行されたワークフローでデプロイされるため,ワークフローの無駄な実行を回避できて良いと思う👌

name: concurrency

on:
  workflow_dispatch:
  push:
    branches:
      - develop
  pull_request:
    branches:
      - develop

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  sleep:
    runs-on: ubuntu-latest
    steps:
      - name: Sleep
        run: sleep 60

自信を持って pytest を活用するためのノウハウが凝縮された「テスト駆動 Python 第2版」を読んだ

「テスト駆動 Python 第2版」を読んだ📕

仕事で pytest を使ってて,もっと自信を持って書けるようになりたいな〜と思っていたら本書を見つけてさっそく読んでみた.pytest の機能・記法・設定・Tips などの理解が深まって本当に読んで良かった❗️フィクスチャ・パラメータ化・モック・プラグイン活用など,今まで何となく書いてたところを自信を持って書けるようになって,仕事で pytest を書くのが楽しくなった🦄

もちろん pytest の公式ドキュメントを読むべきだし,本書の内容の多くは公式ドキュメントにも載っているとは思うけど,本書の翻訳はとても読みやすく,pytest の全体像をサッと把握できて,また Cards というサンプルアプリケーションを題材に実際に pytest を試しながら読み進められるから本書を読む価値はあると思う.個人的には本当に読んで良かったな〜と感じてる👍

docs.pytest.org

目次

目次をザッと見て,気になる Chapter があったら読んでみると良いかと👌

  • Part.1: pytest の主力機能
    • Chapter.1: はじめての pytest
    • Chapter.2: テスト関数を書く
    • Chapter.3: pytest のフィクスチャ
    • Chapter.4: 組み込みフィクスチャ
    • Chapter.5: パラメータ化
    • Chapter.6: マーカー
  • Part.2: プロジェクトに取り組む
    • Chapter.7: 戦略
    • Chapter.8: 設定ファイル
    • Chapter.9: カバレッジ
    • Chapter.10: モック
    • Chapter.11: tox と継続的インテグレーション
    • Chapter.12: スクリプトとアプリケーションのテスト
    • Chapter.13: テストの失敗をデバッグする
  • Part.3: ブースターロケット
    • Chapter.14: サードパーティプラグイン
    • Chapter.15: プラグインの作成
    • Chapter.16: 高度なパラメータ化

本書で使う Cards アプリケーションのコードは原著サイトから ZIP でダウンロードできる.

pragprog.com

Chapter.4

pytest で一時的なディレクトリを作れる組み込みフィクスチャ tmp_path(function スコープ)と tmp_path_factory(session スコープ)はさっそく使えそうだった.

docs.pytest.org

他にも Chapter.4 で紹介されてた組み込みフィクスチャは便利で capsys は別途試して簡単にまとめた.

kakakakakku.hatenablog.com

Chapter.8

pytest.initestpaths を設定するのは明確にはなるけど冗長だよなぁ〜と思っていたらtestpaths を指定しておくと pytest 開始時の時間を少し節約できる」と書いてあって発見だった👀ある程度プロジェクトの規模が大きくないと差は出なさそうではあるけど知れて良かった情報の一つだった👍

[pytest]
testpaths = tests

docs.pytest.org

Chapter.12

スクリプトとテストコードを src ディレクトリと tests ディレクトリに分割したら import できずにハマるというのはよくあると思う💨僕自身も最初ハマって先輩に相談して教えてもらった経緯もあったりする.本書の第2版では Chapter.12 に Python の検索パスの解説が追加されていて良かった❗️本書を読んで pytest の import にハマる人が減ると良いなぁ〜 \( 'ω')/

.
├── pytest.ini
├── src
│   └── hello.py
└── tests
    └── test_hello.py

本書では pytest.inipythonpath を設定する例が紹介されていた.

[pytest]
pythonpath = src

もちろん pytest.ini ではなく pyproject.toml に設定することもできる👌

[tool.pytest.ini_options]
pythonpath = "src"

Chapter.14

pytest プラグインは今までほとんど活用できてなかった💨 pytest サイトの Plugin List を見ながら気になったプラグインをさっそく導入してみて便利❗️

github.com

github.com

github.com

github.com

Chapter.16

@pytest.mark.parametrize でパラメータ化するのは普段から使っているけど,idids にテスト識別子を設定するという Tips は今まで活用できてなかった.確かにパラメータ化したテストで失敗すると判別しにくく感じるときもあった.さっそく仕事でも使うようにした👌

docs.pytest.org

その他

他に読書メモに残したことを箇条書きにしておく❗️

  • pytest --setup-show でフィクスチャの実行順をログに出力できる
  • pytest --tb=no でテスト失敗時のトレースバックを非表示にできる
  • pytest --showlocals でテスト失敗時にローカル変数を表示できる
  • conftest.py でフィクスチャを共有できる
  • @pytest.fixture の名前を変更できる
  • requests をモックできる Responses が便利そう

誤植

出版社サイトに掲載されていない誤植を見つけたのでメモしておく📝

  • P.120: 対処できるしょうか。対処できるでしょうか。
  • P.122: 簡単かかもしれないが簡単かもしれないが

www.shoeisha.co.jp

X ポスト🔗

pytest の capsys で stdout(標準出力)と stderr(標準エラー)をテストする

pytest の capsys を使うと Python スクリプトで出力する stdout(標準出力)と stderr(標準エラー)をテストできる❗️関数の実行結果ではなく,その途中に出力するログに着目したい場面もあって便利〜 \( 'ω')/

docs.pytest.org

👾 src/app.py

hello() 関数は HelloWorld! を stdout と stderr に出力して,version() 関数は Python バージョンを stdout に出力する.サンプルコードなので特に意味はないけど今回はこの関数をテスト対象にする💡

import platform
import sys


def hello():
    print('Hello')
    print('World!', file=sys.stderr)


def version():
    print(platform.python_version())

👾 tests/test_app.py

テストコードでは capsys.readouterr() を使って stdout と stderr を取得して簡単に assert できる👌

from app import hello, version


def test_main(capsys):
    hello()
    captured = capsys.readouterr()
    assert captured.out == 'Hello\n'
    assert captured.err == 'World!\n'


def test_version(capsys):
    version()
    captured = capsys.readouterr()
    assert captured.out == '3.12.2\n'

テスト実行

テストできた👌

$ pytest .
===================================================== test session starts =====================================================
(中略)
configfile: pytest.ini
collected 2 items

tests/test_app.py ..                                                                                                    [100%]

====================================================== 2 passed in 0.01s ======================================================

参考資料

capsys「テスト駆動 Python 第2版」の CHAPTER 4 にも載ってた📕

Terraform で無料利用枠の VPC IP Address Manager (IPAM) を設定する

2023年11月から VPC IP Address Manager (IPAM)「無料枠利用枠」が追加されて Public IP Insights などの機能が無料で使えるようになった💡そして,2024年2月から課金対象になった IPv4 の最適化のために Public IP Insights を使いたいという場面もあると思う.

aws.amazon.com

aws.amazon.com

Terraform で試す

実は Terraform AWS Provider では今まで aws_vpc_ipamtier はサポートされていなかった.今日(2024年3月29日)にリリースされた v5.43.0 でついにサポートされた❗️待ってました〜 \( 'ω')/

github.com

👾 ipam.tf

設定自体は簡単で aws_vpc_ipamtier = "free" を追加すれば OK👌デフォルトは advanced なので注意しておくと良さそう.あと今回は operating_regions にバージニア北部リージョンを設定した💡もちろん複数リージョンを設定することもできる.

resource "aws_vpc_ipam" "main" {
  tier = "free"
  operating_regions {
    region_name = "us-east-1"
  }
}

関連記事

AWS CDK で VPC IP Address Manager (IPAM) を設定する記事は過去に書いているので参考まで〜📝

kakakakakku.hatenablog.com