kakakakakku blog

Weekly Tech Blog: Keep on Learning!

GitHub リポジトリで「リリースノート」を自動的に作ろう

GitHub にはリリースノートを自動的に作る機能があって,マージされたプルリクエストをまとめたりできる👌 OSS ライブラリで semver に沿ってリリースノートを作るのも便利だし,仕事で使っているプライベートリポジトリでも「いつどのプルリクエストがデプロイされたのか」をパッと確認することができて便利❗️

機能を試すだけなら簡単で,GitHub リポジトリで Releases > Draft a new release > Generate release notes と選択するとデフォルト設定でリリースノートを自動的に作ってくれる \( 'ω')/

docs.github.com

リリースノートをカスタマイズする

👾 .github/release.yml

リリースノートの本文をカスタマイズするために .github/release.yml ファイルを作る📝 設定はいくつかあって詳しくはドキュメントに載っているけど,今回はできる限りシンプルな設定にしてみた👌簡単に言うと Dependabot 経由のプルリクエスト(デフォルトで dependencies ラベルが付く)とそれ以外のプルリクエストをカテゴライズしてまとめている❗️

changelog:
  categories:
    - title: Dependencies 🤖
      labels:
        - dependencies
    - title: All Changes
      labels:
        - "*"

ドキュメントに載っている例だともっと細かくて,Semver-Major ラベルを付けたプルリクエストは Breaking Changes 🛠 にカテゴライズして,Semver-Minor ラベルを付けたプルリクエストは Exciting New Features 🎉 にカテゴライズしている💡

# .github/release.yml

changelog:
  exclude:
    labels:
      - ignore-for-release
    authors:
      - octocat
  categories:
    - title: Breaking Changes 🛠
      labels:
        - Semver-Major
        - breaking-change
    - title: Exciting New Features 🎉
      labels:
        - Semver-Minor
        - enhancement
    - title: Other Changes
      labels:
        - "*"

gh release コマンド

そして,リリースノートを自動的に作るときは GitHub リポジトリでポチポチすることもできるけど,gh release コマンドでシュッと作ることもできる👌

$ gh release create v1.0.0 --generate-notes

cli.github.com

GitHub Actions でリリースノートを自動的に作る

さらに自動化を推進するために GitHub Actions でリリースブランチ(main ブランチ・prd ブランチなど)にプルリクエストをマージしたら自動的にリリースノートを作れるようにする❗️

今回は softprops/action-gh-release を使う.個人的に一番使いやすそうだった.ちなみに GitHub Actions 公式の actions/create-release は2021年にアーカイブされている😇

github.com

👾 .github/workflows/create-release.yml

ザッとこんな感じ👌今回は main ブランチにプルリクエストをマージしたら実行するようにした.そして,個人プロジェクトでは semver は必要なく,リリース名(タグ名)はタイムスタンプにした.ちなみにデフォルトでは GitHub リポジトリのデフォルトブランチに対してリリースを作るけど,target_commitish パラメータを指定すれば任意のブランチを指定できる.

name: Create Release

on:
  push:
    branches:
      - main

env:
  TZ: Asia/Tokyo

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "TAG_NAME=$(date +'%Y%m%d-%H%M')" >> ${GITHUB_ENV}
      - name: Create Release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: ${{ env.TAG_NAME }}
          generate_release_notes: true
          target_commitish: main

動作確認

個人的に Terraform の検証をするのに使っているサンドボックスリポジトリに導入してみて,2週間ほど運用しているけど,期待通りにリリースノートを作れている👏

これは便利だ〜 \( 'ω')/

AWS CDK で Service Quotas のクォータをモニタリングする CloudWatch Alarm を設定する

特にプロダクション環境でウェブサービスを稼働させるときに AWS サービスのクォータ(サービス制限)を理解して運用することが重要で,例えば AWS Well-Architected Framework (Reliability Pillar) の REL01-BP04 では Not configuring monitoring to check for service quota thresholds というアンチパターンが紹介されていたりもする❗️

docs.aws.amazon.com

Service Quotas でクォータの使用状況をモニタリングする

実は Amazon CloudWatch で Service Quotas 使用状況をモニタリングすることができる🚨モニタリングできるサービスとメトリクスは以下のドキュメントに載っている.しかしサービスによっては詳細に載っていないこともあって判断しにくく,Service Quotas コンソールでメトリクスを選択して「モニタリング」タブと「アラーム」タブが表示されていればモニタリングできて,モニタリングできない場合は「リクエスト履歴」タブのみ表示されるので判断できる👌

docs.aws.amazon.com

Amazon SageMaker: Number of instances across all processing jobs

クォータによってメトリクスの設定が異なるため,実装する前にマネジメントコンソールからアラートを作って設定を確認しておくと良いと思う👌

具体例を挙げると,AWS Lambda のクォータ Concurrent executions (L-B99A9384) だと AWS/Lambda 名前空間の ConcurrentExecutions メトリクスを使って,Amazon DynamoDB のクォータ Maximum number of tables (L-F98FE922) だと AWS/Usage 名前空間の ResourceCount (TableCount) メトリクスを使う.そして,Amazon SageMaker のクォータ Number of instances across all processing jobs (L-F311B08F) だと AWS/Usage 名前空間の ResourceCount (processing-job/total_instance_count) メトリクスを使う.

👾 lib/service-quotas.ts

今回はサンプルとして Amazon SageMaker のクォータ Number of instances across all processing jobs (L-F311B08F) を使う❗️実装上のポイントは Amazon CloudWatch メトリクスの数式でクォータの使用状況を返す SERVICE_QUOTA 関数を使うところ \( 'ω')/ 今回アラームアクションは割愛しているけど,実際には Amazon SNS トピックなどを設定しておくと良いと思う.

docs.aws.amazon.com

import {
    Duration,
    Stack,
    StackProps,
    aws_cloudwatch,
} from 'aws-cdk-lib'
import { Construct } from 'constructs'

export class ServiceQuotasStack extends Stack {
    constructor(scope: Construct, id: string, props: StackProps) {
        super(scope, id, props)

        const mathExpression = new aws_cloudwatch.MathExpression({
            expression: '(usage_data/SERVICE_QUOTA(usage_data))*100',
            label: '% 使用率',
            usingMetrics: {
                usage_data: new aws_cloudwatch.Metric({
                    namespace: 'AWS/Usage',
                    metricName: 'ResourceCount',
                    dimensionsMap: {
                        Type: 'Resource',
                        Service: 'SageMaker',
                        Resource: 'processing-job/total_instance_count',
                        Class: 'None',
                    },
                    statistic: 'Maximum',
                }),
            },
            period: Duration.hours(1),
        })

        mathExpression.createAlarm(this, 'QuotasAlarm_L-F311B08F', {
            alarmName: 'Number of instances across all processing jobs',
            threshold: 50,
            evaluationPeriods: 10,
            comparisonOperator: aws_cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
        })
    }
}

デプロイ確認

デプロイするとマネジメントコンソールから作ったデフォルトのアラートとほとんど同じ設定になっていた❗️

関連記事

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

Step Functions の新機能「変数」と「JSONata」を AWS と LocalStack で試す

2024年11月22日に AWS Step Functions で新機能「変数 (variables)」「JSONata」がサポートされた❗️

aws.amazon.com

特に「変数」は待望の機能なんじゃないかな〜と思う.今までは AWS Step Functions でタスク結果を引き回すときにどうしてもバケツリレーが必要で,正直 ResultSelector / ResultPath という構文も難しく(何度書いても忘れてしまう😇)ある程度複雑なワークフローを実装するときはデータシュミレーターがないと無理に思えるほどだった.個人的には AWS Step Functions は動くようになったら最高に便利だけどイメージ通りに実装するまでの過程が結構大変〜というイメージがある💨

変数と JSONata を試す

さっそく変数と JSONata を試してみる❗️今回は AWS Lambda 関数から出力された数値同士を「掛け算」するサンプルにする.実は今までの AWS Step Functions 組み込み関数では States.MathAdd を使った「足し算」しかサポートされてなく,過去に困った経験があった.

docs.aws.amazon.com

AWS Step Functions ワークフロー

以下のようなワークフローを作った.AWS Lambda 関数 returnXreturnY はランダムな整数を返して結果を「変数」設定し,最後の Pass では「JSONata」を使って returnXreturnY の値を計算(掛け算)する👌

ステートマシンは必要最低限にしていて,ポイントをザッと以下に挙げる📝

  • QueryLanguageJSONata を指定する
  • Assign を使って AWS Lambda 関数 returnXreturnY の結果 {% $states.result.body %} を変数に設定する
  • JSONata 式 {% $x * $y %} で計算(掛け算)する
{
  "QueryLanguage": "JSONata",
  "StartAt": "returnX",
  "States": {
    "returnX": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:000000000000:function:returnX",
      "Assign": {
        "x": "{% $states.result.body %}"
      },
      "Next": "returnY"
    },
    "returnY": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:000000000000:function:returnY",
      "Assign": {
        "y": "{% $states.result.body %}"
      },
      "Next": "multiplication"
    },
    "multiplication": {
      "Type": "Pass",
      "Output": {
        "multiplication": "{% $x * $y %}"
      },
      "End": true
    }
  }
}

AWS Lambda 関数 returnXreturnY の実装はシンプル💡

import json
import random

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': random.randint(1, 100)
    }

ちなみに 0 ≤ n < 1 の範囲でランダムな値を取得するなら JSONata の $random() 関数で表現できてしまう.あくまで今回は AWS Lambda 関数で何かしらの処理を実行するサンプルとして見てもらえればと👌

docs.jsonata.org

実行結果

AWS Step Functions ワークフローを実行すると期待通りに「変数」「JSONata」を使えた❗️

注意点

今回のリリースと同時に今まで何度もお世話になったデータフローシュミレーターがメンテナンスされなくなっていた😇

LocalStack で変数と JSONata を試す

今回さらにスゴイのは LocalStack も同時に変数と JSONata をサポートしている点で,リリースノートにも LocalStack の紹介文が載っていた❗️

We have also partnered with LocalStack and Datadog to ensure that their local emulation and observability experiences are updated to support Variables and JSONata.

そして LocalStack 側のブログにも記事が出ている📝

blog.localstack.cloud

正確には LocalStack v4.0.1 でサポートされているため,今回は最新の LocalStack v4.0.2 で試す.

github.com

AWS Step Functions ワークフロー

以下の AWS SAM テンプレートを準備した.マネジメントコンソールで試した構成とほぼ同じ👌

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31

Resources:
  FunctionReturnX:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: returnX
      CodeUri: ./src
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
  FunctionReturnY:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: returnY
      CodeUri: ./src
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
  StateMachine:
    Type: AWS::Serverless::StateMachine
    Properties:
      Name: sandbox
      DefinitionUri: ./sandbox.asl.json
      DefinitionSubstitutions:
        FunctionXArn: !GetAtt FunctionReturnX.Arn
        FunctionYArn: !GetAtt FunctionReturnY.Arn

ステートマシン sandbox.asl.json もほぼ同じで,AWS Lambda 関数名の ARN を AWS SAM テンプレートから渡すところが違う👌

{
  "QueryLanguage": "JSONata",
  "StartAt": "returnX",
  "States": {
    "returnX": {
      "Type": "Task",
      "Resource": "${FunctionXArn}",
      "Assign": {
        "x": "{% $states.result.body %}"
      },
      "Next": "returnY"
    },
    "returnY": {
      "Type": "Task",
      "Resource": "${FunctionYArn}",
      "Assign": {
        "y": "{% $states.result.body %}"
      },
      "Next": "multiplication"
    },
    "multiplication": {
      "Type": "Pass",
      "Output": {
        "multiplication": "{% $x * $y %}"
      },
      "End": true
    }
  }
}

次に LocalStack にデプロイすると LocalStack Resource Browser で確認できる❗️

$ samlocal build 
$ samlocal deploy

そして LocalStack 上の AWS Step Functions ワークフローを実行すると,{\"multiplication\":1344} と出力されていて期待通りに計算(掛け算)できている👏

最高だ〜 \( 'ω')/

$ awslocal stepfunctions start-execution --state-machine-arn arn:aws:states:ap-northeast-1:000000000000:stateMachine:sandbox
{
    "executionArn": "arn:aws:states:ap-northeast-1:000000000000:execution:sandbox:ac69989b-6569-4881-aea7-23de22d124ba",
    "startDate": "2024-11-28T00:00:00.000000+09:00"
}

$ awslocal stepfunctions describe-execution --execution-arn arn:aws:states:ap-northeast-1:000000000000:execution:sandbox:ac69989b-6569-4881-aea7-23de22d124ba
{
    "executionArn": "arn:aws:states:ap-northeast-1:000000000000:execution:sandbox:ac69989b-6569-4881-aea7-23de22d124ba",
    "stateMachineArn": "arn:aws:states:ap-northeast-1:000000000000:stateMachine:sandbox",
    "name": "ac69989b-6569-4881-aea7-23de22d124ba",
    "status": "SUCCEEDED",
    "startDate": "2024-11-28T00:00:00.000000+09:00",
    "stopDate": "2024-11-28T00:00:00.000000+09:00",
    "input": "{}",
    "inputDetails": {
        "included": true
    },
    "output": "{\"multiplication\":1344}",
    "outputDetails": {
        "included": true
    }
}

LocalStack Resource Browser でも実行結果を確認できた❗️(今のところ変数は表示されていなさそうだった)

関連記事

aws.amazon.com

関連ドキュメント

docs.jsonata.org

docs.aws.amazon.com

Terraform で Service-Linked Role(サービスにリンクされたロール)を作る

マネジメントコンソールを使ってリソースを設定していると自動的に「Service-Linked Role(サービスにリンクされたロール)」が作られていることがある💡実は AWS CloudFormation や Terraform を使って Service-Linked Role を IaC (Infrastructure as Code) で管理することもできて,今回はお試しとして Terraform の aws_iam_service_linked_role リソースを使って AWS Config の Service-Linked Role を作ってみる👌

👾 iam.tf

aws_iam_service_linked_role リソースの aws_service_name に AWS Config を表す config.amazonaws.com を設定しておけば OK👌 簡単❗️

resource "aws_iam_service_linked_role" "config" {
  aws_service_name = "config.amazonaws.com"
}

docs.aws.amazon.com

ちなみに Service-Linked Role をサポートしているサービス一覧は以下のドキュメントで確認できる📝

docs.aws.amazon.com

デプロイ確認

Terraform コードを apply すると Service-Linked Role AWSServiceRoleForConfig を追加できていた \( 'ω')/

AWS Security Hub と AWS Config

AWS Config には Service-Linked Role AWSServiceRoleForConfig もしくは マネージドポリシー AWS_ConfigRoleAWSConfigRole ではなく)をアタッチした IAM Role を使うとドキュメントには書いてある📝実際にポリシーを比較しても基本的には同じ設定になっていた.

docs.aws.amazon.com

しかし AWS Security Hub のコントロール [Config.1] AWS Config should be enabled and use the service-linked role for resource recording はデフォルトで Service-Linked Role AWSServiceRoleForConfig を使うことを要求していて,マネージドポリシー AWS_ConfigRole をアタッチした IAM Role を使っていると警告が出てしまう(includeConfigServiceLinkedRoleCheck パラメータで無効化することは可能).

よって,特殊な要件がなく AWS Security Hub に準拠するのであれば Service-Linked Role を使っておくのが良さそうだな〜と思った🤔

docs.aws.amazon.com

生成 AI パスポート試験(2024年 第3回)を受験してみた

2024年10月18日(受験可能期間は10月1日〜10月31日)に「生成 AI パスポート試験(2024年 第3回)」を受験して合格した👌試験自体は IBT (Internet Based Testing) だけど結果はすぐに出ず,2024年11月18日に発表された.個人的に結構イイ試験だな〜と感じたので「試験の紹介を目的として」出題内容には触れず簡単に振り返っておこうと思う.

guga.or.jp

試験概要

「生成 AI パスポート試験」はその名前の通り,最近よく話題になる「生成 AI」の基礎知識を問う試験になっていて,ウェブサイトには「生成 AI リスクを予防する資格試験」と表現されていたりもする.よって,少なくともこのぐらいは知っておくと良いぞ〜というポイント(歴史・技術・活用テクニックなど)を理解していることを証明できる💡

出題範囲(2024年 第3回 前提)

出題範囲はシラバス(生成 AI パスポート シラバス 8.03 最新確定版)に詳しく載っていて,ある程度理解していればシラバスを見ると「あ〜こういう感じか〜」と把握できると思う.ちなみにシラバスを見て「ちょっと古いのでは...?」と感じる人もいると思っていて,実は次回開催からはシラバスが改訂されるため,それに関しては記事の最後に紹介する❗️

  • 第1章: AI(人工知能)
  • 第2章: 生成 AI(ジェネレーティブ AI)
  • 第3章: 現在の生成 AI(ジェネレーティブ AI)の動向
  • 第4章: 情報リテラシー・基本理念とAI社会原則
  • 第5章: テキスト生成 AI のプロンプト制作と実例

あと試験としては合格率が高く難易度は低めだと思う.

  • 2024年 第2回(合格率 78.76%)
  • 2024年 第3回(合格率 75.76%)

guga.or.jp

guga.or.jp

なぜ受験したか

自分自身はソフトウェアエンジニアとして日々生成 AI を活用していて,ある程度の理解と体験があるためシラバスを見て基本的にはわかるかな〜という感じだった.よって,資格試験の受験者層とは少し外れている可能性はあるけど,今後もっと生成 AI が普及するためには重要な資格なのかと考えて,どんな資格試験なのか実際に体験しておきたいというモチベーションがあった💪

試験対策

書籍(テキスト・問題集)や研修・試験対策コンテンツなど十分に揃っていると思う.

今回は「生成 AI パスポート公式テキスト 第2版(現在 Amazon で買えるのは第3版だけど読んだのは第2版)」「生成 AI パスポート テキスト & 問題集」をザッと読んだ📕内容的には「公式テキスト」の方が詳しく解説されているけど,あくまでテキスト(教科書)なので,模擬テストを解きながら勉強するなら「テキスト & 問題集」の方が良いと思う.内容的には似ていて,両方読む必要はないかな〜という印象だった.

生成AIパスポート テキスト&問題集

生成AIパスポート テキスト&問題集

  • 日本能率協会マネジメントセンター
Amazon

あとは「おとなもこどもも知りたい 生成 AI の教室」も読んだ📕たまたま子供がこの本を読んでいて,読ませてもらったけど,結構「生成 AI パスポート試験」の出題範囲とカブっていておすすめ❗️小学生でも読める本だからイメージしやすく,本格的な試験対策に入る前に読んでおくと良いと思う.

他に Transformer / GAN / LSTM などの理解は YouTube「スタビジ」の解説動画を観た😀

www.youtube.com

さらにポッドキャスト「Misreading Chat」は普段から聴いていて,そういえば過去に GAN / VAE / Stable Diffusion 関連の論文紹介エピソードがあったな〜と思い出して,改めて聴き直したりもした👂️

misreading.chat

misreading.chat

misreading.chat

ザッとこんな感じ❗️よって,直接的に試験対策をするというよりは,出題範囲で理解が浅いな〜と感じた部分を中心に学び直していた感じだった \( 'ω')/

試験当日

試験自体は IBT で自宅から受験できる👌受験可能期間が1ヶ月間もあって,時間調整しやすいのは良かった.「IBT 受験に必要な機器および受験環境」「禁止事項」はウェブサイトに載っている📝

guga.or.jp

僕はよく AWS 認定試験・Kubernetes 認定資格・Terraform 認定試験などを受験していて,オンライン受験には慣れているため,普段と同じ環境で受験した.オペレーターに監視されることはなかった.

出題範囲(2025年2月以降)

実は次回開催(2025年2月)から出題範囲が改訂されるとアナウンスされている💡シラバス(シラバス改定 2025年2月試験版)も公開されていて,例えば GPT-4o / Claude / Gemini / Sora なども出題範囲になっていたり,AI 事業者ガイドライン(第1.0版)前提で改訂されていてイイ❗️試験自体の鮮度が保たれていることは重要だと思う.

www.meti.go.jp

さらに「生成 AI パスポート試験」の良いところに「生成 AI パスポート 資格更新テスト」という仕組みがあって,新シラバスに沿った知識を証明するために問題数を減らして再受験することができる👌

guga.or.jp

まとめ

個人的にイイ試験だと思う❗️受験して良かった.もし興味あるぞ〜って思ったら次回開催(2025年2月)を申し込んでみると良いじゃないでしょうか😀(申し込み期限は2025年1月31日📅)

1点改善点を挙げるなら IBT なのに合否発表まで遅すぎるのでもっと早く発表されると良いな〜とは思う.