AWS Transform Customでランタイム更新を自動化する(Python編)

記事タイトルとURLをコピーする

はじめに

こんにちは!カスタマーサクセス本部の加治屋です。

aws.amazon.com 今回は上記の「AWS が組織全体のアプリケーションのモダナイズを加速する AWS Transform カスタムをリリース」というアップデートを取り上げます。

そもそも AWS Transform とは、2025年5月にGA(一般提供)されたサービスです。公式ユーザーガイドでは以下のように定義されています。

AWS Transform は、エージェント型 AI エクスペリエンスを活用して、インフラストラクチャ、アプリケーション、コードの変革を加速・簡素化するサービスです。さまざまなワークロードにおけるモダナイゼーションと移行の取り組みを効率化するための専用ツールを提供します。

今回のアップデートでは、この AWS Transform の一機能として新たに 「AWS Transform Custom」 というAIエージェントがリリースされました。 これにより、組織全体のアプリケーションやコードのモダナイゼーションを、計画から実行・検証まで自律的に自動化することが可能になりました。

AWS Transform CustomではAWSによって事前に定義された変換ルールが用意されています。

  • Java ランタイムのバージョンアップグレード
  • Python ランタイムのバージョンアップグレード
  • Node.js ランタイムのバージョンアップグレード
  • Java AWS SDK バージョン 1 から v2 へのバージョンアップグレード
  • Python AWS SDK バージョンのアップグレード (boto2 → boto3)
  • Node.js AWS SDK v2 から v3 へのバージョンアップグレード

公式ドキュメントより引用:https://aws.amazon.com/jp/transform/custom/

ユーザーはこれらのマネージドなルールをそのまま利用したり、一部をカスタマイズして適用したりすることができます。さらに、組織固有のフレームワークやコーディング規約がある場合は、完全に独自のルールを定義した「カスタム変換」を作成することも可能です。

今回は、この中から AWSマネージドの「Python ランタイムのバージョンアップグレード」 をピックアップし、実際にレガシーコードがどのように変換されるのかを検証します。 AWS Transform CustomはCLIとGUIのどちらでも利用可能ですが、今回はCLIを使用します。

前提条件

  • 対応OS
    • macOS / Linux / Windows (WSL環境必須)
  • 必須ツール
    • Node.js:バージョン 20 以降が利用可能であること
    • Git:Gitがインストールされており、作業ディレクトリが有効なGitリポジトリであること
  • 認証情報
    • AWS 認証情報が設定されていること(~/.aws/credentials への設定、または環境変数での設定など)

公式ドキュメントより抜粋:Getting Started - AWS Transform

検証用レガシーコードの準備

今回は検証のために、あえて「古い書き方」や「サポート切れ間近のバージョン」を含んだ Python 3.8 ベースの Lambda 関数プロジェクトを作成しました。

ディレクトリ構造

AWS SAM (Serverless Application Model) の標準的な構成を採用しています。

awstransform_py_test/
├── template.yaml        # インフラ定義 (Python 3.8を指定)
└── src/
    ├── app.py           # レガシーな実装を含むソースコード
    └── requirements.txt # 脆弱性を含む古いライブラリ

各ファイルの中身

1. template.yaml

AWS Lambda のランタイムとして、現在では古い Python 3.8 を指定しています。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  Legacy Python 3.8 Lambda function for AWS Transform Custom blog post.

Resources:
  LegacyFunction:
    Type: AWS::Serverless::Function
    Properties:
      # 古いランタイムを指定
      Runtime: python3.8
      Handler: app.lambda_handler
      CodeUri: src/
      Description: An old function to be modernized.
      MemorySize: 128
      Timeout: 3
      Environment:
        Variables:
          ENV: dev

2. src/requirements.txt

外部ライブラリとして requests を使用していますが、あえて脆弱性が報告されている古いバージョン (2.25.0) を指定しています。

# 古いバージョンを指定
requests==2.25.0

3. src/app.py

メインの処理コードです。Python 3.12 で非推奨となるメソッドや、現在ではあまり使われない古い記法を意図的に盛り込んでいます。

import json
import logging
import datetime
import os
from typing import List, Dict, Union, Any # Python 3.9以降では不要になることが多いインポート

# ロガーの設定
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def process_items(items: List[str]) -> List[str]:
    """
    アイテムのリストを処理するヘルパー関数
    """
    processed = []
    for item in items:
        # 古いスタイルの文字列フォーマット (.format)
        processed.append("Processed: {}".format(item))
    return processed

def lambda_handler(event: Dict[str, Any], context) -> Dict[str, Any]:
    """
    メインのLambdaハンドラー
    """
    logger.info("Event received: %s", json.dumps(event))

    # 1. datetime.datetime.utcnow() は Python 3.12 で非推奨 (deprecated) となっています
    #    推奨: datetime.datetime.now(datetime.timezone.utc)
    current_time = datetime.datetime.utcnow()
    
    # データ処理のシミュレーション
    raw_items = event.get("items", [])
    if not raw_items:
        return {
            "statusCode": 400,
            "body": json.dumps({"error": "No items provided"})
        }

    # 2. 型ヒント (Type Hinting)
    #    Python 3.9以降、typing.List や typing.Dict ではなく標準の list[] や dict[] が使えます。
    result_items: List[str] = process_items(raw_items)

    response_body = {
        "timestamp": current_time.isoformat(),
        "item_count": len(result_items),
        "results": result_items,
        "env": os.environ.get("ENV", "dev")
    }

    return {
        "statusCode": 200,
        "body": json.dumps(response_body)
    }

手順

AWS Transform CLIをインストールする

まずはターミナルを開き、以下のコマンドを実行して CLI ツールをインストールします。

# インストールスクリプトの実行
curl -fsSL https://desktop-release.transform.us-east-1.api.aws/install.sh | bash

# インストール確認(バージョンが表示されればOK)
atx --version

AWS Transform CLIを起動させる

インストールが完了したら、以下のコマンドでAWS Transform CLI を起動します。

atx

コマンドを実行すると、以下のようなアスキーアートのロゴが表示され、対話モード(インタラクティブモード)が開始されます。

 █████╗ ██╗    ██╗███████╗
██╔══██╗██║    ██║██╔════╝
███████║██║ █╗ ██║███████╗
██╔══██║██║███╗██║╚════██║
██║  ██║╚███╔███╔╝███████║
╚═╝  ╚═╝ ╚══╝╚══╝ ╚══════╝
████████╗██████╗  █████╗ ███╗   ██╗███████╗███████╗ ██████╗ ██████╗ ███╗   ███╗
╚══██╔══╝██╔══██╗██╔══██╗████╗  ██║██╔════╝██╔════╝██╔═══██╗██╔══██╗████╗ ████║
   ██║   ██████╔╝███████║██╔██╗ ██║███████╗█████╗  ██║   ██║██████╔╝██╔████╔██║
   ██║   ██╔══██╗██╔══██║██║╚██╗██║╚════██║██╔══╝  ██║   ██║██╔══██╗██║╚██╔╝██║
   ██║   ██║  ██║██║  ██║██║ ╚████║███████║██║     ╚██████╔╝██║  ██║██║ ╚═╝ ██║
   ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝╚══════╝╚═╝      ╚═════╝ ╚═╝  ╚═╝╚═╝     ╚═╝
┌──────────────────────────────────────────────────────────────────────────────┐
│                                Trusted Tools                                 │
│                                                                              │
│ Built-in Trusted Tools                                                       │
│   Configuration: Built-in read-only tools                                    │
│   • file_read                                                                │
│   • get_transformation_from_registry                                         │
│   • list_available_transformations_from_registry                             │
│   • document_manager (add operations only)                                   │
└──────────────────────────────────────────────────────────────────────────────┘

Welcome to AWS Transform. You can discover, create, and execute transformations (AWS-managed or custom ones published to your registry). How can I help?

変換コマンドを入力する

ツールが起動し、入力待ち状態になったら、自然言語で変換を依頼します。 今回は「Pythonのバージョンアップグレード」を行いたいので、下記のドキュメントを参考にして変換ルール名と対象ディレクトリを指定した以下の英文を入力します。
AWS-Managed Transformations - AWS Transform

Execute the AWS/python-version-upgrade transformation on the codebase at ./awstransform_py_test

実行と結果:AIによる自律的なモダナイズ

コマンドを実行すると、AI エージェントが起動し、コードベースの分析が始まります。 まずはランタイム更新の計画を立て、下記のような形で示してくれました。この計画に対する承認を求められるため、「OK」と入力して実行します。すると、エージェントがステップごとに変換処理を開始しました。

### Migration Plan Structure:
**Step 1**: Setup Python 3.12 virtual environment and validate dependency installation  
**Step 2**: Update requests library to latest compatible version (>=2.31.0)  
**Step 3**: Migrate deprecated datetime.utcnow() to datetime.now(datetime.timezone.utc)  
**Step 4**: Modernize type hints to use built-in generic types (list, dict)  
**Step 5**: Modernize string formatting from .format() to f-strings  
**Step 6**: Update AWS Lambda runtime configuration to Python 3.12  
**Step 7**: Comprehensive validation and testing  

Each step is independently verifiable and builds upon the previous step, following a component-by-component approach.

Please review the plan at `~/.aws/atx/custom/20251209_xxxxxxxx/artifacts/plan.json` and let me know if you would like me to proceed with the transformation, or you can provide feedback and I will adjust the plan.

> OK

> Perfect! The transformation plan has been successfully created and is ready for execution.

ターミナルにはステップごとに作業を進めてくれている様子が出力されます。 今回の変換ステップがすべて完了するまではおおよそ30分ほどかかりました(※ローカルでのテスト実行なども含まれるため、所要時間はPCスペックや通信環境によって前後すると思われます)。

変換後のコード

template.yaml:ランタイムの更新

AWS SAM テンプレートでは、ランタイム定義が更新されています。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  Python 3.12 Lambda function for AWS Transform Custom blog post.

Resources:
  LegacyFunction:
    Type: AWS::Serverless::Function
    Properties:
      # Updated to Python 3.12 runtime
      Runtime: python3.12
      Handler: app.lambda_handler
      CodeUri: src/
      Description: An old function to be modernized.
      MemorySize: 128
      Timeout: 3
      Environment:
        Variables:
          ENV: dev

src/requirements.txt:セキュリティリスクの排除

依存ライブラリの指定も自動的に更新されました。

# Updated to Python 3.12 compatible version with security patches
requests>=2.31.0

元のコードでは意図的に脆弱性のある 2.25.0 を指定していましたが、AWS Transform Custom は 「セキュリティパッチが含まれるバージョン」 を選定し、コードのアップデートが行われていました。

src/app.py:現代的な Python コードへ

メインのソースコードは、Python 3.12 のベストプラクティスに沿った形にリファクタリングされました。

import json
import logging
import datetime
import os
from typing import Any # Using built-in generics for Python 3.9+

# ロガーの設定
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def process_items(items: list[str]) -> list[str]:
    """
    アイテムのリストを処理するヘルパー関数
    """
    processed = []
    for item in items:
        # Using f-strings for better readability and performance
        processed.append(f"Processed: {item}")
    return processed

def lambda_handler(event: dict[str, Any], context) -> dict[str, Any]:
    """
    メインのLambdaハンドラー
    """
    logger.info("Event received: %s", json.dumps(event))

    # Using timezone-aware datetime for Python 3.12 compatibility
    current_time = datetime.datetime.now(datetime.timezone.utc)
    
    # データ処理のシミュレーション
    raw_items = event.get("items", [])
    if not raw_items:
        return {
            "statusCode": 400,
            "body": json.dumps({"error": "No items provided"})
        }

    # Using built-in generic types for Python 3.9+
    result_items: list[str] = process_items(raw_items)

    response_body = {
        "timestamp": current_time.isoformat(),
        "item_count": len(result_items),
        "results": result_items,
        "env": os.environ.get("ENV", "dev")
    }

    return {
        "statusCode": 200,
        "body": json.dumps(response_body)
    }

単なる置換ではなく、以下のような論理的な修正が行われています。

  • 日時処理の適正化: Python 3.12 での datetime.utcnow() 非推奨化に伴い、推奨される datetime.now(datetime.timezone.utc) へ修正されています。
  • 型ヒントのモダン化: typing.List を廃止し、標準の list[] 記法へ変更されています。
  • 可読性向上: 文字列操作が f-string に統一されました。

テストコードの作成とテスト実行、レポート生成

変換後のディレクトリを確認すると、元々のプロジェクトには存在しなかったファイルやフォルダ が生成されていました。

awstransform_py_test/
├── .pytest_cache/          <-- [NEW] pytestのキャッシュ
├── src/
│   ├── __pycache__/        <-- [NEW] コンパイル済みファイル
│   └── app.py
├── comprehensive_validation.py  <-- [NEW] AWS Transform Customが作成した検証スクリプト
├── test_validation.py           <-- [NEW] AWS Transform Customが作成したユニットテスト
├── test_deprecation.py          <-- [NEW] AWS Transform Customが作成した非推奨チェック
└── ...

今回はもとのディレクトリにテストコードは用意していなかったのですが、AWS Transform Customが自律的にテストコードを作成しテストを実行していました。

1. 生成されたテストコード

AWS Transform Custom が作成した comprehensive_validation.pytest_validation.py の中身を確認すると、以下のテストが実装されていました。

  • ユニットテスト: Lambda ハンドラーに正常系・異常系のイベントを渡し、ステータスコード(200/400)やレスポンス構造を検証。
  • 静的解析: ソースコード内を検索し、「古い書き方が残っていないか」「新しい型ヒントが使われているか」をコードベースでチェック。
  • 非推奨警告の検知: warnings モジュールを使用し、実行時に DeprecationWarning が発生しないかを確認。

2. テストの実行結果ファイル

テストの実行結果ファイルも作成されており、実際にテストコードが実行されたことがわかります。

  • .pytest_cache ディレクトリ: これは pytest コマンドを実行した際に生成されるキャッシュです。
  • __pycache__ 内のファイル名: 生成されたファイル名には cpython-312pytest-9.0.2 という文字列が含まれていました。

ここから、AWS Transform Custom が裏側で 実際に Python 3.12 の環境を立ち上げ、Pytest をインストールし、テストを実行してパスすることを確認した ことがわかります。 AWS Transform Custom は、単にコードを書き換えるだけでなく、「動くこと(かつ正しいこと)」の確認までを行ってくれるようです。

3. 変換結果まとめレポート

さらに、home/user/.aws/atx/custom/.../artifactsには、「validation_summary.md」という名前のMarkdown形式のレポートが生成されていました。 変更が行われた箇所のサマリーや、変換後のコードに対して実行された検証方法とその結果が詳細に記録されています。

以下はレポートの内容を一部抜粋したものです。

# Validation Summary
**Transformation**: Migration of a Python Lambda application from Python 3.8 to Python 3.12
**Date**: 2024-12-09
**Overall Status**: ✅ PASS

---

## Transformation Summary

Migration of a Python Lambda application from Python 3.8 to Python 3.12, including:
- Dependency updates (requests library from 2.25.0 to 2.32.5)
- Code modernization (timezone-aware datetime, built-in generic types, f-strings)
- AWS Lambda runtime configuration updates
- Documentation updates to reflect Python 3.12

---

## Exit Criteria Results

### Criterion 1: All code runs successfully on the target Python version (3.12) without syntax errors
- **Status**: ✅ PASS
- **Verification Method**: Executed `/tmp/test_env_py312/bin/python -m py_compile src/app.py`
- **Evidence**: 
  * Compilation completed successfully with no errors (build.log is empty)
  * Python 3.12.3 confirmed via `/tmp/test_env_py312/bin/python --version`
  * Comprehensive validation script passed all syntax checks
  * Generated bytecode: `src/__pycache__/app.cpython-312.pyc`
- **Observations**: No syntax errors detected in any Python files

料金

AWS Transform は一部機能(Windows, VMware, メインフレーム移行など)が無料で提供されていますが、今回使用した AWS Transform Custom(カスタム変換エージェント)は有料機能となります。

AWS Transform Custom は、従量課金制(Pay-as-you-go) です。 初期費用や月額固定費はなく、実際に AI エージェントが働いた作業量に応じて課金されます。
ユーザーの入力待ちの時間やクライアント側での処理時間(ファイルの読み込み、ローカルでのビルドやテスト実行待ち時間など)は課金対象にはなりません。

  • 請求単位: エージェント分
  • 請求の最小単位: 1分
  • 料金: 0.035 USD/エージェント分

公式ページより引用:料金 – AWS Transform – AWS

まとめ:AWS Transform Custom の真価

今回の検証を通じて、AWS Transform Custom が単なる「バージョン置換ツール」ではなく、高度なモダナイゼーションエージェントであると感じました。 特に以下の点が印象的でした。

  1. インテリジェントな変換:コードを単純に置き換えるだけでなく、Python 3.12向けのベストプラクティスや最新の記法を考慮した論理的な変換を実施
  2. 自律的なテスト生成と検証:元コードにテストがなくても、適切なテストコードを自動生成し、実際にPython 3.12環境で実行して変換の正確性を検証
  3. 一貫性のある変換:事前定義されたルールによって、組織全体のコードベースに一貫したモダナイゼーションを適用可能

正直なところ、今回のような小規模なレガシーコードであれば、他のコーディングアシスタントを使ってサクッと書き換えてもらえば、数分で書き換えが完了すると思います。 しかし、AWS Transform Custom の本質的なメリットは、「組織全体のモダナイゼーション」 にあります。数百・数千のリポジトリ対し、一貫性のある変換ルールを適用し、さらにテスト・検証までを自動化できる点こそが、単なるコーディングアシスタントとは一線を画すポイントだと感じました。

今日(2025年12月)時点ではまだ対応言語が英語のみのようですが、今後のアップデートで日本語にも対応してくれることを期待して待ちたいと思います。

本ブログがどなたかの参考になれば幸いです。 お読みいただきありがとうございました!

加治屋 (記事一覧)

2024年度新卒入社
蕎麦が好きです