kakakakakku blog

Weekly Tech Blog: Keep on Learning!

新機能 Terraform Actions に入門できるチュートリアル「Invoke actions with Terraform」

2025年12月に正式リリースとなった「Terraform Actions」に入門できるチュートリアル「Invoke actions with Terraform」を試してみた👌 AWS と Azure で試せるようになっていて,今回は AWS にした.

developer.hashicorp.com

Terraform Actions

Terraform Actions はリソースの "デプロイ後" などのタイミングで何かしらの自動化処理をトリガーする仕組みで,インフラ管理の Day.0 を「Build(ビルド)」・Day.1 を「Deploy(デプロイ)」と位置付けて,Terraform Actions は Day.2「Manage(管理)」に位置付けられる仕組みと言える.詳しくは HashiCorp ブログ Terraform actions now generally available, simplifying Day 2 infrastructure management で紹介されている📝

ブログ記事では以下の例が載っていた💡

  • AWS Lambda 関数の実行
  • Amazon CloudFront のキャッシュ無効化
  • Amazon SNS 経由のアラート通知

In AWS environments managed by Terraform, a number of Day 2 tasks emerge that often require teams to switch to the AWS console. Some examples include manually invoking Lambda functions, creating invalidation requests for CloudFront’s cache, or sending alerts and notifications via SNS. With actions, Terraform users are able to accomplish all of these tasks and more, without leaving Terraform workflows.

ちなみに最新の Terraform AWS Provider だと以下の Terraform Actions もサポートされている.

  • AWS Step Functions ワークフローの実行
  • AWS CodeBuild ビルドの実行

Invoke actions with Terraform

チュートリアルでは以下のようなアーキテクチャをデプロイする.Amazon API Gateway + AWS Lambda 関数 + Amazon SQS キューというよくある形ではあるけど,Terraform で AWS Lambda 関数を作成 (after_create) もしくは更新 (after_update) したときに Terraform Actions で同じ AWS Lambda 関数を実行 (invoke) する.

あくまで個人的には今回のアーキテクチャだと「なぜ Terraform Actions で AWS Lambda 関数を実行する必要があるの?」という理由が弱くて,便利だな〜と感じられるサンプルではないように感じた.言い換えると「とりあえず Terraform Actions に入門する Hello World 的な内容」という感じ😅

まずは main.tf の実装を確認して,terraform plan コマンドと terraform apply コマンドを実行してデプロイする.動作確認として Amazon API Gateway の /job エンドポイントに POST リクエストを投げれば OK👌 Amazon SQS キューに Invoke lambda from curl というメッセージが登録されていた.

$ curl --request POST \
  --header "Content-Type: application/json" \
  --data '{"message": "Invoke lambda from curl", "type": "CLI"}' \
  "$(terraform output -raw http_api_url)"

次に Terraform Actions を実装する.よく使うのは resourcedata だけど,Terraform Actions では action で実装する.今回は aws_lambda_invoke アクションを使う.

action "aws_lambda_invoke" "api_handler" {
  config {
    function_name = aws_lambda_function.api_handler.function_name
    payload = jsonencode({
      message = "Invoke lambda from action",
      type    = "test"
    })
  }
}

なお Terraform Actions は terraform apply コマンドの -invoke オプションで個別に実行することもできる.実行すると Amazon SQS キューに Invoke lambda from action というメッセージが登録されていた.

$ terraform apply -invoke=action.aws_lambda_invoke.api_handler
(中略)
Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Actions: 1 invoked.

今度は aws_lambda_function リソースに lifecycle.action_trigger として Terraform Actions を設定する.ポイントは action はあくまで実行する対象を設定していて,トリガーに関してはリソース側に設定する必要があるということ.

今回の例で言うと,前述した通り Terraform で AWS Lambda 関数を作成 (after_create) もしくは更新 (after_update) したときにトリガーする.

resource "aws_lambda_function" "api_handler" {
  function_name = "${var.project_name}-handler"
  runtime       = "python3.14"
  handler       = "index.handler"
  role          = aws_iam_role.lambda_role.arn

  s3_bucket = aws_s3_bucket.lambda_bucket.id
  s3_key    = aws_s3_object.lambda_object.key
  source_code_hash = data.archive_file.lambda_archive.output_base64sha256

  environment {
    variables = {
      QUEUE_URL = aws_sqs_queue.job_queue.url
    }
  }

  lifecycle {
    action_trigger {
      events  = [after_create, after_update]
      actions = [action.aws_lambda_invoke.api_handler]
    }
  }
}

最後に AWS Lambda 関数のコードを修正してデプロイすると,Terraform Actions 経由でトリガーされて Amazon SQS キューに Invoke lambda from action というメッセージがもう一つ登録されていた👌

まとめ

Terraform Actions に入門できるチュートリアル「Invoke actions with Terraform」を試してみた.今回のアーキテクチャだと「なぜ Terraform Actions で AWS Lambda 関数を実行する必要があるの?」という理由が弱いように感じたけど,とりあえず Terraform Actions を体験したいならサクッと試せて良いと思う.

developer.hashicorp.com

他にも Terraform AWS Provider でサポートされている Terraform Actions があるので,現場で使えそうなインフラ管理の Day.2 シナリオを考えてみたいと思う💪

PSR-4 違反を検出する composer dump-autoload --optimize --strict-psr コマンド

Composer の composer dump-autoload --optimize --strict-psr コマンドを使うと PSR-4 (Autoloader) 違反を検出できる.

www.php-fig.org

getcomposer.org

PHP_CodeSniffer だと PSR-4 違反は検出できず,GitHub Actions でサクッと PSR-4 を検出するならコマンド実行で良さそうだな〜と思って試してみた💪

.github/workflows/php-check-psr4.yml

ワークフローは以下のような感じになる.特別なことはしてなくて PHP をセットアップしてから composer dump-autoload --optimize --strict-psr コマンドを実行している❗️必要最低限の PSR-4 違反の検出であれば十分そう.

name: php-check-psr4

on:
  push:
    branches:
      - main

jobs:
  php-check-psr4:
    runs-on: ubuntu-slim
    steps:
      - uses: actions/checkout@v6
      - uses: shivammathur/setup-php@v2
        with:
          php-version: 8.4
      - name: Check PSR-4
        run: composer dump-autoload --optimize --strict-psr

実際に PSR-4 違反のコードを push すると期待値通りにエラーになった.

Terraform と lambroll で LocalStack に Lambda 関数をデプロイする

lambroll を使って AWS Lambda 関数をデプロイしてる環境で動作確認のために LocalStack にもデプロイしたいという相談があって,検証環境を作る機会があった.結果的に問題なくデプロイできた👌個人環境で検証したことをまとめておく.

github.com

今回の構成としては AWS リソースを Terraform でデプロイしつつ,AWS Lambda 関数のコードは GitHub Actions + lambroll でデプロイする.LocalStack に関しては同じく Terraform でデプロイしつつ,AWS Lambda 関数のコードはローカル環境から lambroll deploy コマンドを実行する.

1. Terraform

👾 main.tf

まず,Terraform では IAM Role・AWS Lambda 関数(空っぽ)・Amazon SQS キューをデプロイしておく.AWS Lambda 関数のコードは lambroll でデプロイするため archive_file データソースを使ってダミーコードを設定しておく.

resource "aws_iam_role" "sandbox" {
  name = "sandbox-role"

  assume_role_policy = jsonencode(
    {
      Version = "2012-10-17"
      Statement = [
        {
          Action = "sts:AssumeRole"
          Effect = "Allow"
          Principal = {
            Service = "lambda.amazonaws.com"
          }
        }
      ]
    }
  )
}

resource "aws_iam_role_policy_attachment" "sqs" {
  role       = aws_iam_role.sandbox.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonSQSFullAccess"
}

data "archive_file" "dummy" {
  type = "zip"
  source {
    content  = "dummy"
    filename = "app.py"
  }
  output_path = "${path.module}/dummy.zip"
}

resource "aws_lambda_function" "sandbox" {
  function_name    = "sandbox-function"
  role             = aws_iam_role.sandbox.arn
  handler          = "app.lambda_handler"
  runtime          = "python3.13"
  filename         = data.archive_file.dummy.output_path
  source_code_hash = data.archive_file.dummy.output_base64sha256

  lifecycle {
    ignore_changes = [
      timeout,
      environment
    ]
  }
}

resource "aws_sqs_queue" "sandbox" {
  name = "sandbox-queue"
}

👾 backend.tf

tfstate は S3 Backend を使って Amazon S3 バケットで管理する.

terraform {
  backend "s3" {
    region       = "ap-northeast-1"
    bucket       = "xxxxx"
    key          = "terraform.tfstate"
    use_lockfile = true
  }
}

デプロイ確認

IAM Role・AWS Lambda 関数(空っぽ)・Amazon SQS キューをデプロイできた.

2. lambroll

👾 functions/app.py

今回はサンプルとして AWS Lambda 関数から Amazon SQS キューにメッセージを送信するシンプルな実装にした.

import json
import os
import uuid

import boto3

sqs = boto3.client('sqs')


def lambda_handler(event, context):
    sqs.send_message(
        QueueUrl=os.environ['QUEUE_URL'],
        MessageBody=json.dumps(
            {
                'id': str(uuid.uuid4()),
            },
        ),
    )

👾 functions/function.json

lambroll の function.json では tfstate 記法を使って tfstate から値を取得するようにしている🐑

{
  "Architectures": [
    "x86_64"
  ],
  "Environment": {
    "Variables": {
      "QUEUE_URL": "{{ tfstate `aws_sqs_queue.sandbox.url` }}"
    }
  },
  "EphemeralStorage": {
    "Size": 512
  },
  "FunctionName": "sandbox-function",
  "Handler": "app.lambda_handler",
  "MemorySize": 128,
  "Role": "{{ tfstate `aws_iam_role.sandbox.arn` }}",
  "Runtime": "python3.13",
  "Timeout": 30
}

👾 .github/workflows/deploy.yml

最後に GitHub Actions + lambroll で AWS Lambda 関数のコードをデプロイする.

name: Deploy Lambda function

on:
  push:
    branches:
      - main
    paths:
      - ".github/workflows/deploy.yml"
      - "functions/**"
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-slim
    permissions:
      contents: read
      id-token: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v5
        with:
          role-to-assume: arn:aws:iam::000000000000:role/xxxxx
          aws-region: ap-northeast-1

      - name: Install lambroll
        uses: fujiwara/lambroll@v1
        with:
          version: v1.4.1

      - name: Deploy Lambda
        run: lambroll deploy --tfstate s3://xxxxx/terraform.tfstate
        working-directory: functions

デプロイ確認

GitHub Actions 経由で AWS Lambda 関数のコードをデプロイできた.

動作確認

AWS Lambda 関数を実行すると Amazon SQS キューにメッセージを送信できていた👌

$ aws lambda invoke --function-name sandbox-function response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

3. LocalStack

デプロイ

AWS アカウントで動作確認ができたため今度は LocalStack にデプロイする.まずは localstack start -d コマンドで LocalStack を起動しておく.

$ localstack start -d

次に LocalStack Terraform CLI(tflocal コマンド)を使って LocalStack に plan / apply を実行すると問題なくデプロイできる.

$ tflocal plan
$ tflocal apply
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

github.com

IAM Role・AWS Lambda 関数(空っぽ)・Amazon SQS キューをデプロイできた.

次に lambroll で AWS Lambda 関数のコードを LocalStack にデプロイする.lambroll は --endpoint オプションをサポートしているため LocalStack を指定している👌

しかしこのままだと --tfstate オプションで指定した S3 Backend を参照できず error:failed to read tfstate from s3://xxxxx/terraform.tfstate: operation error S3: GetObject, https response error StatusCode: 403 というエラーが出てしまう🔥今回は lambroll が内部的に依存している tfstate-lookup でサポートされている環境変数 AWS_ENDPOINT_URL_S3 に LocalStack の S3 エンドポイントを指定することで解消した.他の選択肢ある!?

github.com

$ export AWS_ENDPOINT_URL_S3=http://s3.localhost.localstack.cloud:4566
$ lambroll deploy --endpoint http://localhost:4566 --tfstate s3://xxxxx/terraform.tfstate

最後は動作確認をする.LocalStack AWS CLI(awslocal コマンド)で AWS Lambda 関数を実行すると Amazon SQS キューにメッセージを送信できていた👌

github.com

$ awslocal lambda invoke --function-name sandbox-function response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

Terraform で Amazon Athena の「マネージドクエリ結果」を設定する

2025年12月4日にリリースされた Terraform AWS Provider v6.25.0 で Amazon Athena の「マネージドクエリ結果 (Managed query results)」がサポートされた💡

github.com

マネージドクエリ結果は2025年6月にリリースされた新機能で,クエリ結果を保存する Amazon S3 バケットを管理する必要がなく Amazon Athena に任せることができる.

aws.amazon.com

もちろんマネージドクエリ結果の制約もあって,詳しくはドキュメントに載っている.

docs.aws.amazon.com

実装は簡単で aws_athena_workgroupconfigurationmanaged_query_results_configuration を追加すれば OK👌クエリ結果を暗号化する設定をすることもできる.

resource "aws_athena_workgroup" "sandbox" {
  name = "sandbox"

  configuration {
    managed_query_results_configuration {
      enabled = true
    }
  }
}

terraform apply を実行すると期待値通りにマネージドクエリ結果(マネジメントコンソールの表記だと「Athena マネージドストレージ」)を設定できていた❗️

2025年の振り返りと2026年の抱負

2025年の振り返り🎉

お仕事を楽しくたくさん頑張った

2023年4月からフリーランスのソフトウェアエンジニアになって,早くも2年半以上でもう少しで3年になる.毎日楽しく働けていて最高👌お仕事の相談も十分にもらえていて,タイミングが合わずにお断りせざるを得ないようなこともあってゴメンナサイ!

特に2025年9月からは大きく4つのお仕事を並行していて,すべて仕事内容が異なるためコンテキストスイッチを楽しみながら進められたのも良かった.アーキテクチャ設計・バックエンド開発・インフラ構築・コスト最適化・DevOps 推進・AI 活用推進・アジャイル開発導入支援・次期テックリード育成など幅広くやっているような感じ❗️

  • ソフトウェア開発全般(歴史のあるプロダクトのモダナイズと技術組織のマネジメント支援など)
  • ソフトウェア開発全般(新規プロダクト開発など)
  • 技術顧問(アーキテクチャ設計など)
  • 研修講師(生成 AI 関連)

研修講師の仕事は出張が多くて,普段から自宅にこもっている僕にとっては慣れない生活でもあった.それでも講師って最高だなと思える1年だった.「とにかくわかりやすかったです」「こんなにモチベーションが高まったのははじめてです」などのフィードバックをもらえて頑張って良かった〜と思える場面も多くあった.

  • 2025年7月: 岐阜出張
  • 2025年9月: 岐阜出張
  • 2025年10月: 沖縄出張(3回)
  • 2025年12月: 金沢出張(2回)

とまぁお仕事を楽しくたくさん頑張ったけど,もっともっと頑張りたくてお仕事用のウェブサイトも用意してある.空いている稼働枠に変化があるときに更新してる感じ📝どうしてもタイミング次第になってしまう場合もあるけど,モダンな技術スタックを使った案件も好きだし,プロダクトも開発組織もレガシーでモダン化を推進する案件も好きだし,インフラエンジニア不在で AI に任せてたけど限界なので立て直す案件も好きなので,楽しそうなお仕事があったらご連絡いただければと🙏

kakakakakku.github.io

お仕事の内容は変わらないけど,2025年4月に法人化(株式会社)をしたのも大きな変化の一つだった.会社運営は今まで経験がなくて,司法書士の先生や税理士の先生にサポートしてもらいながらアレコレするのも勉強になって良かった.

「LocalStack 実践入門」の続編を3冊公開した

2024年8月に LocalStack 実践入門 | AWS アプリケーション開発ワークショップを公開して,2025年には続編として3冊(サーバレスパターン・Terraform・Pulumi)執筆した.特に LocalStack 実践入門 | AWS サーバレスパターン開発ワークショップは評判が良くて「やってみました!」「LocalStack でここまでできるんですね!」というコメントを多くもらえた😀

お仕事で LocalStack の導入支援をする機会もあって,個人プロジェクトがお仕事につながるような体験もできた!

zenn.dev

zenn.dev

zenn.dev

AWS Community Builders 2025 (Serverless) に選ばれた

2025年は AWS Community Builders 2025 (Serverless) に選ばれたことも印象的なイベントだった.僕自身はコミュニティ活動はほぼしてなく,テックブログと Zenn Book の執筆を中心にアウトプットするスタイルではあるけど評価してもらえたのは嬉しかった.2025年は継続的にテックブログを書きつつ,Serverless Land の AWS Serverless Patterns Collection にコントリビュートしていた.2026年も更新できるようにどんどんアウトプットしていこうと思う💪

kakakakakku.hatenablog.com

やり切れなかったこともあった

  • YouTube「カックマイクラ実況」は2025年9月で更新が止まってしまった🙅
  • 2025年10月から執筆していた新作の Zenn Book を公開できなかった🙅

Write Code Every Day

2025年も毎日のように仕事・個人プロジェクト・勉強をしていて,結果的に Write Code Every Day になっていて良かった🌸

テックブログ

2025年は「週1記事(52記事)」のノルマとストレッチゴールの「100記事」を掲げていた.1週も落とすことなく毎週書き続けて,最終的には「年間109記事」を達成できた❗️さらにはてなブログの読者登録数も気付いたら 1000 を突破して嬉しかった \( 'ω')/

累計ブクマ数は「2116621977 (+811)」だった.基本的に個人的な学習ログを中心にアウトプットしているため伸びるとは思ってなく,少しでも誰かの参考になれば嬉しいな〜という気持ちでテックブログを書いている😀

グラフ的に少し変化している箇所は「習慣化 振り返り(2024年7-12月)」「CodeDeploy いらず!ECS Blue/Green デプロイを試す」「エンジニアリングリーダーの実践的なプラクティスとは「エンジニアリングリーダー ―技術組織を育てるリーダーシップとセルフマネジメント」を読んだ」だった.

プルリクエスト

詳しくは振り返り記事にまとめた.

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

読んだ本

詳しくは振り返り記事にまとめた.

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

習慣化

詳しくは振り返り記事にまとめた.

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

資格

2025年6月に HashiCorp 公式の認定試験「HashiCorp Certified: Terraform Authoring and Operations Professional」を受験して合格できたのは印象に残っている❗️4時間のラボ試験(Linux 環境が与えられて・Terraform コードを書いて・plan と apply を実行する)でトラブルシューティングをしているような感覚になって楽しかったし,合格したときは達成感もあった.生成 AI にコードを書いてもらう時代だからこそ「生成 AI の支援がなくてもできる」っていう証明になりそう.

kakakakakku.hatenablog.com

2026年の抱負✨

2026年も変わらずにお仕事も個人プロジェクトも楽しく頑張ろうと思う💪

そして「インプット/アウトプット」も続ける.というよりは意識せずとも続くような状態になっている😀2026年も同じノルマとストレッチゴールを目指す📝

  • ブログ「週1記事(52記事)」ノルマ
  • ストレッチゴールとして1年間で「100記事」

まとめ

2026年も楽しむぞ〜❗️よろしくお願いしまーすッッッ \( 'ω')/

過去の振り返り