CDKを利用したRDSオプショングループの管理手順

CDKを使ってRDSを作る際、オプショングループを使用することがあります。

docs.aws.amazon.com

簡単な実装としては以下のような感じ。

import * as cdk from 'aws-cdk-lib';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';

export class MyRdsStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const vpc = new ec2.Vpc(this, 'MyVpc', {
      maxAzs: 2
    });

    const optionGroup = new rds.OptionGroup(this, 'MyOptionGroup', {
      engine: rds.DatabaseInstanceEngine.mysql({
        version: rds.MysqlEngineVersion.VER_8_0_43
      }),
      configurations: []
    });

    new rds.DatabaseInstance(this, 'MyRdsInstance', {
      engine: rds.DatabaseInstanceEngine.mysql({
        version: rds.MysqlEngineVersion.VER_8_0_43
      }),
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
      vpc,
      credentials: rds.Credentials.fromGeneratedSecret('admin'),
      multiAz: false,
      allocatedStorage: 20,
      deleteAutomatedBackups: false,
      deletionProtection: false,
      optionGroup
    });
  }
}

ここでは簡単にconfigurationsを空にしています。

これをcdk delpoyでデプロイし、その後cdk destroyすると失敗します。

14:45:50 | DELETE_FAILED        | AWS::RDS::OptionGroup                       |
MyOptionGroup23FF99C3
The option group 'myrdsstack-myoptiongroup23ff99c3-xxxxxxxxxx' cannot be dele
ted because it is in use. (Service: Rds, Status Code: 400, Request ID: cebcf741
-88c9-aaaa-00000-xxxxxxxxxx) (SDK Attempt Count: 1)

オプショングループが削除できないというエラーメッセージです。

原因は単純で、RDS削除時にスナップショットが取られているからです。CDKにてremovalPolicyのデフォルト値がSNAPSHOTになっています。

docs.aws.amazon.com

できればRDSのremovalPolicyと同期して欲しいのですが、そうはなっていないので以下のように実装します。

(省略)

    const optionGroup = new rds.OptionGroup(this, 'MyOptionGroup', {
      engine: rds.DatabaseInstanceEngine.mysql({
        version: rds.MysqlEngineVersion.VER_8_0_43
      }),
      configurations: []
    });
    // ↓追記
    optionGroup.applyRemovalPolicy(cdk.RemovalPolicy.RETAIN);
(省略)

これでcdk destroyが成功します。

% cdk destroy
Are you sure you want to delete: MyRdsStack (y/n) y
MyRdsStack: destroying... [1/1]

 ✅  MyRdsStack: destroyed
%

もちろん、このままですとオプショングループは削除されずに残ったままとなるので、必要であれば手作業で削除する必要があります。

一時的な利用なのでオプショングループ含めて削除したいというのであれば、RDSの作成を以下のようにします。

    new rds.DatabaseInstance(this, 'MyRdsInstance', {
      engine: rds.DatabaseInstanceEngine.mysql({
        version: rds.MysqlEngineVersion.VER_8_0_43
      }),
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
      vpc,
      credentials: rds.Credentials.fromGeneratedSecret('admin'),
      multiAz: false,
      backupRetention: cdk.Duration.days(0),
      allocatedStorage: 20,
      deleteAutomatedBackups: false,
      deletionProtection: false,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      optionGroup
    });

removalPolicyDESTROYを指定するだけでなく、backupRetentionを0日(Duration.days(0))としてバックアップを残さないようにすることが必要です。これでRDS削除時にオプショングループも削除されます。

Amazon Q developerにおけるプロジェクトルールの実装例その2

先日書いたプロジェクトルールの実装例の続きです。

miyohide.hatenablog.com

前回書いたプロジェクトルールを数日間試してみたのですが、あまりよい流れとならなかったので再度練り直しました。結果として、以下のような形になりました。

# 基本

- 日本語で応答してください
- 必要に応じて、ユーザに質問を行い要求を明確にしてください
- GitHubへアクセスが必要な場合は、GitHub CLIの`gh`コマンドを使ってください

# 作業の定義

それぞれの作業を以下のように定義します。

- 「設計」と指示された場合、指示されたことに対して以下のことを実施してください
    - GitHubにIssueを作成してください。Issueのタイトルは指示された内容を30文字以内にまとめたもの、Issueの内容は指示されたものとしてください。
    - `docs/designs``YYYYMMDD-GitHubのIssueの番号-design.md` という名前のファイルを作成し、記載してください
        - ファイル名の中にある`YYYYMMDD`は`date`コマンドなどを使って現在の日付を正しく取得するようにしてください
    - この段階でコードは絶対に書かないようにしてください
    - この段階では、指示されたことに対してAPIエンドポイント設計やテーブル設計、作成・更新が必要なコードについて考えファイルに出力してください。
- 「実装」と指示された場合、以下のことを実施してください。
    - 同時に指示された`docs/designs`内の`YYYYMMDD-GitHubのIssueの番号-design.md`という名前のファイルの内容をGitHub Issueのコメントとして追加してください
    - GitHub Issueの番号を使って、`feature/GitHubのIssueの番号`というgitのブランチを作成してswitchしてください。このとき、`develop`ブランチを親ブランチとします
    - 指示された内容に基づいてコードを書いてください
    - コードを書き終えたらコミットしてください
- 「実装レビュー」と指示された場合、以下のことを実施してください
    - ブランチ`feature/GitHubのIssueの番号`をGitHubにpushしてください
    - ブランチ`feature/GitHubのIssueの番号`を使ってPull Requestを作成してください。このとき、マージ対象のブランチは`develop`としてください

# `docs`ディレクトリの内容

- `docs/designs/*.md` : 設計資料

# ブランチ戦略

このプロジェクトのブランチ戦略はGitflowを用います。それぞれのブランチの意味は以下の通りです。

- `main` : 本番環境にデプロイされているブランチ
- `develop` : 次のリリースに向けた開発が行われているブランチ
- `feature/*` : 新機能の開発が行われているブランチ
- `release/*` : リリース準備が行われているブランチ
- `hotfix/*` : 本番環境で発生したバグ修正

考え方としては以下の通りです。

  1. 設計作業を実施。Issueに紐付け。設計内容を手元のMarkdownファイルにも保存(AmazonQで実施)
  2. 設計内容を人の目で確認。必要であれば修正を行う
  3. Markdownファイルの内容をもとに実装。Issueも合わせて更新(AmazonQで実施)
  4. 必要であれば人の手で修正。
  5. Pull Requestを作成してレビュー依頼(AmazonQで実施)

あわせてGitのブランチ戦略も必要かと思い、ここではGitFlowを採用しました。GitFlow自身の細かい説明は実施せず、ブランチの内容を補足したぐらいで概ねうまく動いてくれています。

また、GitHub CLIであるghコマンドも詳細を教えなくてもうまく動いてくれます。生成AIにおいては広く使われて、ドキュメントがオープンになってしっかり書かれているもののほうが挙動は安定するかと感じます。

動かした結果例は以下の画像を参照してください。

ちなみに、AmazonQがgradlewコマンドをうまく動かすことができず、bashコマンドを使っているのがちょっとよくわからない。

その他

あとは細かいコーディング規約を追加しました。まだテーブル設計までは試し切れていませんが、こんなものを作ろうと考えています。

プロジェクト内でSQLのコーディングを行う際は下記ルールに従ってください。

# 命名規則

- 予約後(`SELECT``FROM``WHERE`など)は大文字で記述します
- テーブル名、カラム名、ビュー名などのオブジェクト名は小文字で記述します
- 複数の単語からなる名前は、スネークケース(`_`で連結)を使用します
- テーブル名は、そのテーブルが保持するエンティティの複数形を使用します。例えば`users``products`などです。
- カラム名はそのカラムの情報を明確に表す単数形を使用します

# コメント

- テーブルやカラムにはコメントを付与するようにしてください

# 禁止事項

- `SELECT *`は使用しないでください
    - 不要なデータを取得してしまい、パフォーマンスの低下を招く恐れがあるためです。また、スキーマ変更時に予期せぬ挙動を引き起こす可能性があります

# 使用するデータ型

- 文字列データには`VARCHAR`を使用してください。このとき、必ず長さを指定してください。
- できる限りNOT NULL制約をつけてください。
- 日付と時刻のデータにはタイムゾーンが保存できる型を使用してください

これはまだ未検証なので、どこまで意図した通りになるか楽しみです。

Amazon Q developerにおけるプロジェクトルールの実装例

はじめに

Visual Studio CodeなどのIDEAmazon Qを使ってなんらかの処理をさせたい時、プロジェクトルールやコーディング規約など生成させるコードなどになんらかのルールを強制させたいことがあります。これを実現する機能が以下の公式ドキュメントで書かれているプロジェクトルールです。

docs.aws.amazon.com

ここでは、私が実際に使っているプロジェクトルールを紹介します。なお、このプロジェクトルールですが、日々試行錯誤を重ねています。今日時点のものが完成形ではなく、日々修正等を積み重ねていることはご了承ください。

ルールの確認・作成

上記の公式ドキュメントにもありますが、プロジェクトルールはプロジェクトルート/.amazonq/rulesフォルダにMarkdownファイルを作成することで完了します。1つのファイルで完結させる必要もなく、複数のファイルに分割しても良いです。

Visual Studio CodeではAmazon QのChatウィンドウにてRulesがあるのでそれをクリックしたら現在のルールの確認や新規ルールの作成などが行えます。

ルールの作成

Markdownでルールを書くことができるとは言っても、何を書くか悩んで手が止まってしまうことがままあります。わかりやすいものとしてはコーディングルールかなと思います。

コーディングルール

生成AIでコードを生成させるとき、コーディングルールなどで指示をあらかじめ与えておくとそれに従ったコードを生成してくれます。例えば、こんなルールを使っています。

プロジェクト内でJava言語のコーディングを行う際は下記ルールに従ってください。

# 全般

- 1つのファイルに複数のクラスを記載しないようにしてください。
- 1つの行に対して最長100字以内となるように記載してください。100字を超える場合は適宜次の行に記載するようにしてください。
- deprecatedとなっているクラスやメソッド、アノテーションは使わないようにしてください。

# JavaDocについて

- 生成するすべてのメソッドおよびクラスに対してJavadocを記載してください。

# 設定ファイル

- 設定ファイルはproperties形式としてください。YAML形式は使わないでください。

# 生成するファイルのパッケージについて

Spring Bootアプリケーションで必要な各ファイルは下記のパッケージに
`src\main\java\com\example\springaiapp`配下に下記パッケージを配置してください。
それぞれのパッケージがない場合は新規作成してください

## パッケージ一覧

- Controller:Controllerクラスを格納してください。
- Service:Serviceクラスを格納してください。
- Repository:Repositoryクラスを格納してください。

# 命名規則

以下の命名規則に従ってください

## クラスの命名

各クラスのパッケージ名をクラス名のあとに記載してください
例:HogeControllerクラス(Controllerクラスに配置)

# テストファイルの作成について

テストファイルの種類は下記とします。

## Unit Test

- JUnitを利用してください
- テストケースは分岐網羅をカバーするように作成してください。

# フォーマット

- フォーマットは[Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)に従ってください
- コードを生成した場合、Gradleの`spotlessApply`タスクを実行してフォーマットを修正してください

あまり目新しいところはないかと思います。設定ファイルをproperties形式にしているのは、grepをするときに探しやすいかなと思って指示しています。

deprecatedとなっているものを使わないようにと指示していますが、実際にはあまりうまく判断できない感じがします。

一般的な注意事項

一般的な注意事項として、以下の内容を.amazonq/rules以下に保存しておいています。

# 基本

- 日本語で応答してください
- 必要に応じて、ユーザに質問を行い要求を明確にしてください
- GitHubへアクセスが必要な場合は、GitHub CLIの`gh`コマンドを使ってください

# 作業の定義

それぞれの作業を以下のように定義します。

- 「設計」と指示された場合、指示されたことに対して以下のことを実施してください
    - `docs/designs``YYYYMMDD-連番-design.md` という名前のファイルを作成し、記載してください
        - ファイル名の中にある`YYYYMMDD`は`date`コマンドなどを使って現在の日付を正しく取得するようにしてください
        - ファイル名の中にある`連番`は2桁0埋めの1から始まる番号としてください
    - この段階でコードは絶対に書かないようにしてください
    - この段階では、指示されたことに対してAPIエンドポイント設計やテーブル設計、作成・更新が必要なコードについて考えファイルに出力してください。
- 「設計レビュー依頼」と指示された場合、以下のことを実施してください。
    - 同時に指示された`docs/designs`内の`YYYYMMDD-連番-design.md`という名前のファイルの内容をもとにGitHub上でIssueを作成してください
        - Issueのタイトルは指示された内容を30文字以内にまとめたもの、Issueの内容は指示された内容としてください
        - `docs/designs` に作成する`YYYYMMDD-連番-design.md`にはGitHub Issueの番号も追記するようにしてください
    - GitHub Issueの番号を使って、`feature-GitHubのIssueの番号`というgitのブランチを作成してswitchしてください
- 「実装」と指示された場合、 `docs/designs` に記載された内容に基づいて実装してください

# `docs`ディレクトリの内容

- `docs/designs/*.md` : 設計資料

イメージとしては、①何かやりたいことに関する設計と②実装を順番通りに進める形です。

YYYYMMDDは特に指定しないと適当な日付を設定するので「dateコマンドなどを使って〜」と具体的に取得方法を指示しています。GitHubへのアクセスもghコマンドを使用するように具体的に指示していますが、MCP Serverでもよいかもしれません。

プロンプト

この内容を踏まえて、プロンプトには

  • XXXなことを実現するために設計してください
  • docs/designs/YYYYMM-連番-design.mdの内容をもとに実装してください

といった感じで指示を出します。

改善案

とりあえずこんな感じでJavaアプリの開発を進めているのですが、いくつか改善案もあります。

  • 実装時にpull requestの作成を指示する
  • Issueのフォーマットについて指示する
  • GitHub Issueを参照して調査や計画が実行できるようにする
  • deprecatedなものを使わないでと言っているが使うことがある。後の調査でも使っていないと言い張る

ただ、これらのプロンプトエンジニアリングは凝り始めるといつまでもやってしまいそうなので、どこかで区切りを持った方が良いかなとも思います。

Amazon Q Developerを使ったSpring Boot + Spring Securityアプリのバージョンアップ

はじめに

Amazon Q Developerには.NETやJavaのコードをアップグレードする機能があります。

docs.aws.amazon.com

Javaにおいては、Javaのバージョンアップのほか、ライブラリやフレームワークのバージョンアップにも対応しています。全量は以下の公式ページに掲載があります。

docs.aws.amazon.com

対応しているライブラリやフレームワークを眺めているとSpring BootやSpring Framework、Spring Securityだけでなく、junitやMockitoなどテスト関係のライブラリが含まれています。そこで今回は、Spring BootとSpring Securityを使った簡単なWebアプリを対象に実際に動かしてみました。

変換元アプリ

わかりやすいようにSpring Bootのバージョンは2.7.18としました。このバージョンにした理由は、このバージョンに関連するSpring Securityに対して大きな変更が加わっているからです。詳細は以下のブログを参照してください。

spring.io

実装コードは以下の通り。すでに廃止されたWebSecurityConfigurerAdapterを使ったものとしています。

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 認証設定 - インメモリでユーザーを定義
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user")
            .password(passwordEncoder().encode("password"))
            .roles("USER")
            .and()
            .withUser("admin")
            .password(passwordEncoder().encode("admin"))
            .roles("USER", "ADMIN");
    }

    /**
     * 認可設定 - Spring Security 5.3の古い方式
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // 認可設定
            .authorizeRequests()
                .antMatchers("/", "/login", "/css/**", "/js/**").permitAll()
                .antMatchers("/h2-console/**").permitAll() // H2コンソール用
                .anyRequest().authenticated()
                .and()
            // ログインページ設定
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/todos", true)
                .permitAll()
                .and()
            // ログアウト設定
            .logout()
                .logoutSuccessUrl("/login?logout")
                .permitAll()
                .and()
            // H2コンソール用の設定
            .csrf().ignoringAntMatchers("/h2-console/**")
                .and()
            .headers().frameOptions().sameOrigin();
    }
}

ちなみにプロジェクトをVisual Studio Codeで開くと、多くの警告メッセージが出ます。

プロジェクト全体のコード行数は以下となります(clocを使って計測)。

github.com/AlDanial/cloc v 2.06  T=0.04 s (1004.0 files/s, 114786.4 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
HTML                             8            170              2           1667
Java                             9            111             94            454
Bourne Shell                     2             60            170            316
DOS Batch                        2             45              2            236
CSS                              2             51              0            207
JavaScript                       1             48              2            168
XML                              3              4              0            126
Maven                            1             10              5             84
Gradle                           2              5              0             32
Markdown                         1              7              0             23
Properties                       4              0              1             12
JSON                             1              0              0              4
-------------------------------------------------------------------------------
SUM:                            36            511            276           3329
-------------------------------------------------------------------------------

前提

Amazon Q Developerの変換機能にはいくつか前提があります。全量は以下の公式ページを参照してください。

docs.aws.amazon.com

主だったところは、以下かなと思います。

  • Javaのバージョンは8以上
  • Mavenでビルドできること(pom.xmlが存在していること)
    • Gradleはダメです。実際にやってみると、セットアップ時に怒られます。

build.gradleからpom.xmlへの変換はAmazon Q Developerに依頼すると変換してくれるので、あまり障壁ではないですがちょっと面倒です。

なお、必須条件ではないですがJUnitなどでテストコードは書いておいた方が良いです。書いていない場合はAmazon Q Developerで書いてもらうことで対応できるかなと思います。Amazon Q Developerには/test単体テストを作らせる機能があるので、それを利用するのがお手軽かなと思います。

docs.aws.amazon.com

私の場合、generate integration tests for this app.とプロンプトを書いてテストコードを生成させ、作成されたテストコードを手作業で修正する形をとりました。

単体テストはこのようなバージョンアップに対しては壊れやすい気がしたのでintegration testsとしたのがその理由ですが、あまり明確な根拠はないです。

変換

変換はAmazon Q Developerに/transformと入力してenter/returnを押せばOKです。

あとは画面の指示に従います。Javaのバージョンなどを指定します。

すべての設定が完了すると、transformation-plan.mdが作られ、変換が実行されます。

Lines of code in your applicationとして437と算出されました。この行数がどのように算出されたのかがよく分からず。clocで計算したJavaコードの行数は454行、wcコマンドで算出したJavaコードの行数はは662行となり、いずれも一致せず。

変換は約30分かかりました。ソースコードが変更されながら何度もビルドが実行されます。

画面上では確認できませんでしたが、のちほどログ(summary/buildCommandOutput.log)を見るとテストコードを実行するオプションを選択した場合、テストコードの実行も何度も行われます。おそらくですが、ビルドの成功やテストコードの成功が変換処理の正しさを判断する材料としているように見受けられます。このため、変換処理の正しさをAmazon Q Developerに判断させるためにもテストコードは用意した方が良いかと考えます。

最後にsummary/summary.mdが生成され、コード変換の結果がまとめられます。

変換結果詳細

変換結果を詳しくみていきます。

まず、Spring Bootは2.7.18から3.3.4になりました。2025年10月5日時点、Spring Bootの最新バージョンは3.5.6で、3.3.xはOSSのサポート終了となっています。

spring.io

Spring Bootのリリースサイクルが早いとはいえ、これはもうひと頑張りして3.4.xまで上げて欲しかったと思います。

Spring Securityを使っている部分は以下の通り概ねうまく変換できている形です。

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 認証設定 - インメモリでユーザーを定義
     */
    @Bean
    InMemoryUserDetailsManager inMemoryAuthManager() {
        var user = User.builder()
            .username("user")
            .password(passwordEncoder().encode("password"))
            .roles("USER")
            .build();
            
        var admin = User.builder()
            .username("admin")
            .password(passwordEncoder().encode("admin"))
            .roles("USER", "ADMIN")
            .build();
            
        return new InMemoryUserDetailsManager(user, admin);
    }

    /**
     * 認可設定 - Spring Security 5.3の古い方式
     */
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            // 認可設定
            .authorizeHttpRequests(requests -> requests
                .requestMatchers("/", "/login", "/css/**", "/js/**").permitAll()
                .requestMatchers("/h2-console/**").permitAll() // H2コンソール用
                .anyRequest().authenticated())
            // ログインページ設定
            .formLogin(login -> login
                .loginPage("/login")
                .defaultSuccessUrl("/todos", true)
                .permitAll())
            // ログアウト設定
            .logout(logout -> logout
                .logoutSuccessUrl("/login?logout")
                .permitAll())
            // H2コンソール用の設定
            .csrf(csrf -> csrf.ignoringRequestMatchers("/h2-console/**"))
            .headers(headers -> headers.frameOptions(options -> options.sameOrigin()));
        return http.build();
    }
}

一部コメントに古い記述が残っていたりしていますが、テストも通りますし人がここらへんを調べながら実装するのは(Amazon Qの変換時間である)30分ではできないものなので、、良い結果なのではと思います。

その他、Spring Boot 3.0へのバージョンアップとしての変更点の一つであるパッケージ名の変更javax.*からjakarta.*への変更も行われていました。

その他細かい変更点は、GitHub上にあげているソースコードの差分を確認してください。

github.com

結果と考察

Amazon Q DeveloperのJavaアップグレード機能を使って古いSpring Bootアプリのバージョンアップをやってみました。概ね、良い変換結果となりました。私がよいと思ったのは以下の点です。

  1. 概ね正しい変換が行われた
  2. transformation-plan.mdsummary.mdが生成され、何が行われたのか後で振り返れるようになっている
    • 特にsummary.mdの存在は貴重で、このようなドキュメントは往々にして作成が求められるので、自動生成されるのは大変ありがたいです。

一方で、以下の点が気になりました。

  1. Mavenしか対応していない
    • せめてGradleにも対応してほしいです。
    • ローカルにmvnコマンドが必須のようです。Maven wrapperだけで運用していた場合は、環境構築が若干手間取るかもしれません
  2. より新しいSpring Bootのバージョンにアップグレードしてほしい
    • 上でも記しましたが、すでにOSSサポート終了版にアップグレードされるのはもう少しなんとかならないかという思いがあります。
  3. Quotaが低い/Pro版の料金に含まれる行数が低い
    • 今回は非常に単純なTodoアプリを対象としましたが、アプリの対象行数は437行と表示されました。
    • Free版の場合、ジョブあたり1,000行、1ヶ月で2,000行が上限なので、ちょっと複雑なコードを書いていたらすぐFree版のQuotaに引っ掛かります。
    • Pro版は4,000行を超えたものは1行あたり0.03ドルの課金とあります。これが思いの外高いと感じます。
  4. 変換にかかる時間が長い
    • 今回のように非常に単純なTodoアプリでも約30分変換に時間がかかりました。
    • 実行してしまえば、あとは放置して良いのであまり気にしなくても良いかもしれませんが、30分ぐらいはかかることは認識しておいた方がよさそうです。

今回は単純なTodoアプリ+JPAという構成のSpring Bootアプリケーション対して実行しましたが、User GuideをよむとConverting embedded SQLという機能があります。

docs.aws.amazon.com

JPAを使っている以上、SQLが表に出てくることはあまりないのですが、こちらも時を見て試してみたいです。

AWS Certified DevOps Engineer - Professional(DOP-C02)に合格した

先日、AWS認定DevOpsエンジニア - プロフェッショナル(DOP-C02)を受験し、合格しました。

今回の受験は3年前に合格した認定の更新のために受験したものです。その時のブログは以下を参照してください。

miyohide.hatenablog.com

3年も経つとクラウド関連のサービスも色々と変わってきます。また、使わないサービスについては忘れていることも多く、結局はほぼゼロから学び直しという形で試験対策を始めました。

試験範囲の確認

試験対策を始める前に、試験範囲を確認します。以下のページに試験ガイドが公開されているのでそこで問われるサービスの名称を確認しておきます。

aws.amazon.com

前回と違う点として、私が確認した時点での試験ガイド(バージョン1.6)にはCodeCommitの記載がありませんでした。CodeCommitは新規受付を終了しているため、試そうにも試せないのがその要因かなと推察しています。以下のリンクはCodeCommitの新規受付終了のアナウンスが書かれているAWSブログ。

aws.amazon.com

FAQにも「現行のサービスまたは機能が変更されました。〜」の部分にそれらしき記述があります(明確にアナウンスからいつの時点で試験対象外とは書かれていませんが)。

aws.amazon.com

試験対策

Udemy

学習の基本はUdemyの「AWS Certified DevOps Engineer Professional 2025 - DOP-C02」を軸に進めました。

www.udemy.com

個人的にAWS認定試験の学習は上記Udemyの講師であるStephane Maarekの動画を軸に学習しています。試験別の各コンテンツはStephane Maarekのサイトを確認してください。

courses.datacumulus.com

Skill Builder

AWSがSkill Builder上で公式模擬試験を公開しています。これも解いてみます。

skillbuilder.aws

無料ユーザーは20問しか受験できないのですが、どのようなことが問われるのかを把握するにはよいきっかけにはなるかなと思います。単純にサービス名称とその役割を知っているだけだとダメで、具体的な利用シーンやトラブルに対してどのような対策が取れるかを把握する必要があるので、模擬試験を解いた後にUdemyの動画を見直すということを繰り返しました。

Skill Builderには各種サービスの紹介コンテンツもあるのですが、軽くサービス名の紹介にとどまっている感じがしました。サブスクリプション登録してもあまり大きな差は感じられませんでした。このため、サービスの学習にはUdemyコンテンツが良いかなと考えています。

BlackBelt

いわゆるBlackBeltも主要なサービスにおいては見直しました。

aws.amazon.com

ただ、いくつかのサービスは資料自身が古いのが気になりました。例えば、CodePipelineは2020年時点の資料なので、現状を知るのであれば触ってみるかUdemy動画で学習するのが良いかなと思います。

生成AI

3年前の受験と比べて大きく変わったのは生成AIの活用です。学習していてよくわからない部分については生成AIに聞いてみました。

いわゆるプロンプトエンジニアリングには時間を割かず「〜〜について教えて」と聞く形から会話をスタートさせ、だんだんと詳細を聞いていく形にしました。複数の選択肢がある場合に表形式でまとめて整理してもらうと理解が進んでよかったです。

受験

受験の前に、軽食をとっておきます。フルに時間を使うと3時間の試験です。頭フル回転で試験に臨むことになるので、どうしてもお腹が減ります。空腹感を覚えると試験に集中できなくなるため、それを防ぐためにも軽食を取るようにしています。私の場合は、小さいチョコひとかけらぐらいを食べるぐらいです。

試験はテストセンターで受験しました。もう手慣れたもので、受付や本人確認などをささっと終わらせて、受験。

1つ1つの問題文が長く、選択肢もよく似たものが多い感じなので、じっくりと読み込んで受験します。わからない問題や解答に自信がない問題はフラグをつけます。90分で一通り問題を解き終わり一息。この時点でフラグをつけた問題が8問あったので見直しを実施して回答を埋めます。 最後に全問見直しをします。解答に自信がない問題にフラグをつけた結果、最終的に10問フラグがつくことになりました。

試験の採点方法や点数配分については公開されていないのですが、個人的には8割正解したら良いだろうと考えています。このため、今回の試験においては75問中15問は間違えられると考えています。フラグをつけた10問すべて間違えていたとしてもおそらく合格ラインには達するだろうと考え、試験時間を50分残した状態で受験終了しました。

結果発表

試験結果はその場では出ず、待つ必要があります。朝イチで受験した場合、だいたい20時半過ぎぐらいには試験申し込みをしたサイト(Certmetrics.com)の試験履歴から参照できます。

cp.certmetrics.com

結果を確認してほっと一安心。今回はスコア860だったので、少し余裕を持って合格できた感じでした。

Apple Silicon 対応のAWS CLIがリリースされていた

今回もAWS CLIネタ。AWS CLI、2.30.0でApple Silicon対応が謳われていたものの2.30.2まではインストーラーでRosettaが要求されていました。

miyohide.hatenablog.com

その後、2.30.3にてようやく正式対応されました。

ChangeLogにも以下の記載があります。

enhancement:macOS: Added explicit architecture support in PKG installer for universal builds on Macs to prevent Rosetta requirement prompt.

私が試したバージョンは2.30.3よりも進んだ2.30.5ですが、実際にインストールしてみると、Rosettaの要求なしにインストーラーを進めることができます。

そのままインストールを進めると、無事成功。バージョン情報にもexe/arm64Apple Silicon対応版として動いています。

なお、インストーラーを進める途中に、すべてのユーザーにインストールするか、特定のユーザーにインストールするかという選択肢が出てくるのですが、ここではすべてのユーザーにインストールすることをお勧めします。原因は以下のIssue。

github.com

何はともあれ、Apple SiliconでRosettaなしで公式のAWS CLIが動く環境が整いました。

AWS CLIのApple Silicon対応版の状況

先日、AWS CLIApple Silicon 対応版の状況ってどうなっているんだっけと思ってみてみたら、クローズされていました。

github.com

上記は2022年9月にオープンされたIssue。待つこと3年、Apple Siliconに対応したAWS CLIが公開されました。Blogにも書かれています。

aws.amazon.com

喜び勇んで公式ページからダウンロードし、インストールをやってみました。

docs.aws.amazon.com

ですが、あれ?Rosettaのインストールが求められます。

この上記の画面で「今はしない」を選択すると、インストーラーが終了し、AWS CLIがインストールされません。

今回、2.30.0でApple Silicon対応されたということなので、具体的にバージョンを指定したインストーラーもダウンロードして試しましたが、結果は同じ。バージョンを指定したインストーラーのパスは以下の通り。

# 2.30.0
https://awscli.amazonaws.com/AWSCLIV2-2.30.0.pkg
# 2.30.1(さらに更新されたバージョン)
https://awscli.amazonaws.com/AWSCLIV2-2.30.1.pkg

ちなみにIntel Mac上でインストールしてみるとRosettaの確認は求められません(RosettaApple Silicon Mac上でIntel向けのコードを動かすためのものなので、挙動としては正しい)。インストール後、AWS CLI自身のfileコマンドの結果は以下の通り。

見ての通り、Universalアプリになっていて、Intel向け(x86_64)とApple Silicon向け(arm64用)の二つのバイナリが存在します。

macOSのアプリケーション作成には詳しくないのですが、軽く調べた感じ、distribution.xml<option>タグを設定するとよいとのこと。

developer.apple.com

Issueは以下の通り発行されていましたので、同じ内容をコメントしておきました。

github.com

早く治るといいのですが。