【AWS Summit 2026】開発初心者が「AWS Blocks」を使って、簡易生成AIアプリ作ってみた

はじめまして。SCSKの山本です。

このたび「AWS Summit 2026」に参加しましたので、セッションを通じて得られた知見を記事としてご紹介します。

本記事では、「AWS Blocks」というサービスについて、ご紹介いたします。

アジェンダは、以下の通りです。

AWS Blocksとは?

概要

AWS Blocksとは、2026年6月16日にパブリックプレビューとして発表されたサービスです。
(私はSummitに参加した際に初めて知りました、、、)

一言でいうと、AWS Blocksは「アプリケーションコードからAWSインフラを自動生成できる」新しい開発フレームワークです。

Building Blockの考え方

AWS Blocksでは、認証・データベース・ストレージ・AIエージェントなどの機能が「Building Block」として提供されています。

従来はAWSサービスごとに設定や構築が必要でしたが、AWS Blocksでは必要なBuilding Blockを組み合わせるだけでバックエンドを構築できます。

例えば、認証機能やデータベース機能を利用したい場合は、対応するBlockを追加するだけで利用できます。

そのため、開発者はインフラ構築よりもアプリケーション開発に集中できます。

Infrastructure from Code(IfC)

従来のIaC(Infrastructure as Code)では、CDKやCloudFormationを利用してインフラを定義した後にアプリケーションを実装する必要がありました。

一方AWS Blocksでは、「アプリケーションコードから必要なインフラを導き出す」というInfrastructure from Code(IfC)の考え方を採用しています。

開発者はアプリケーションの機能をコードで定義するだけで、必要なAWSリソースが自動生成されるため、インフラを意識する場面を大幅に減らすことができます。

項目 IfC IaC
考え方 アプリコードからインフラを生成 インフラをコード化
主役 アプリケーションコード CDK/CloudFormation
開発順序 アプリ→インフラ インフラ→アプリ

 

AWS Blocks の何がすごいか

結論から言うと、主に以下4点です。

  1. ローカルモック
    AWSアカウントがなくてもローカル環境で動作確認が可能です。   
    AWS環境を準備する前にアプリケーションの開発や検証を進められるため、試行錯誤のサイクルを高速に回せます。
  2. End to Endの型安全性
    アプリから直接呼べる、型安全なAPIで構成されます。    バックエンドで定義したデータ型やAPIの情報がフロントエンドにも反映されます。
    そのため、実行時エラーを減らしながら、安全かつ効率的にアプリケーションを開発できます。
  3. CDK Construct
    AWS Blocksは内部的にAWS CDKを活用しています。   
    ローカル環境で十分に検証したアプリケーションを、そのままAWS環境へデプロイできます。
    さらに、必要に応じてCDKレベルでの細かなカスタマイズも可能です。
  4. 開発から本番まで同じコードで利用可能
    ローカル開発時とAWSデプロイ後でコードを書き換える必要がほとんどありません。   
    「ローカルでは動くがクラウドでは動かない」といった問題を減らし、開発体験の向上につながります。
  5. Agent Steering

    AIコーディングエージェントがAWS Blocksの開発パターンを理解しやすいように設計されています。
    追加設定をほとんど行わなくても、エージェントが適切なBlock選択やコード生成を行いやすくなっており、AI駆動開発との相性が非常に高いことが特徴です。

     

AWS Blocksは単なるバックエンドフレームワークではなく、「開発・インフラ・AIエージェント」をひとつの仕組みとして扱える点が最大の特徴です。
 

実際に検証してみた

ここまで聞くと、AWS Blocksを使えば簡単に開発できそうだと思いますよね!?
そこで、普段の業務では基盤の保守運用やインフラ基盤の設計構築しかまともにしたこと無いの開発初心者の私ですが、
実際にAWS Blocksを使ってみて何かアプリ作ってみることにしました!

前提条件

AWS Blocksを使用するのにあたって、私が使用した環境やソフトウェアは下記の通りです。

  • OS: Windows
  • Node.js: v24.18.0(要件: v22 以降)
  • npm: 11.7.0(要件: v10 以降)
  • エディタ: VS Code
  • aws-cli:2.35.13(AWSアカウント接続に必要)
  • AWS リージョン: 東京 ※デプロイ時
  • AWSアカウント: ローカル開発では不要(デプロイ時のみ必要)
Getting started with AWS Blocks - AWS Blocks
Set up your environment and build your first AWS Blocks application with a type-safe API, data storage, and authenticati...

コマンド1行でセットアップ完了!?

なんと、プロジェクトはコマンド1行で数十秒で作れます!

※テンプレートとして、認証付きのToDoアプリが丸ごと生成されます。

npm create @aws-blocks/blocks-app@latest

 

まだ何も触っていませんが、早速ローカルサーバを立ち上げてみましょう。

npm run dev

 

数十秒待ってみてローカルサーバー立ちあがったので、ブラウザからアクセスしてみます。

サインイン後、、、

 

おおー!特に何もしていませんが、ものの数分で認証付きのTodoアプリが出来上がりました。

ここで満足してしまいそうでしたが、せっかくなのでいろいろいじってみたいと思います!

 

AWS関連の相談窓口チャットボットを作成

何のアプリを作ろうかなと考えた時に、普段業務でよく使うアプリって生成AI系だなと思ったので、
AWS関連の質問に答えてくれるチャットボットを作成することにしました。

以下の手順で作成を進めました。

  1. プロジェクトファイル編集
  2. ローカル検証
  3. デプロイ
  4. 動作確認

※時間があれば、エージェントと合わせて開発までしたかったですが、本記事では手動でコード開発しています。

 

プロジェクトファイル編集

  • src/index.ts:生成AIチャットボットのフロントエンド
    このコードで AWS Blocks 特有なのは、認証機能とAPI呼び出しの部分です。
    authApi や AuthenticatedContent を利用することで、ログイン機能を簡単に実装できます。
    また、api.askAi() を呼び出すだけでバックエンドAPIへアクセスでき、型安全なクライアントコードも自動生成されます。
    これにより、認証やAPI連携を意識せずにアプリケーション開発に集中できます。
/**
 * Frontend — src/index.ts

 * 生成AIチャットボットのフロントエンドです。
 * lit-html を利用してチャット画面を描画し、ユーザーからの質問や送信イベントを処理します。
 * バックエンドとの通信には、`aws-blocks` が自動生成する型安全なAPIクライアントを使用しています。
 * ユーザーの入力内容を生成AIへ送信し、返答を画面に表示します。

 */

import { api, authApi } from "aws-blocks";
import { AccountMenuBar, AuthenticatedContent, onAuthChange } from "@aws-blocks/blocks/ui";
import { html, render } from "lit-html";

// ─── Auth ────────────────────────────────────────────────────────────────────
// Show Account Menu bar that pops open authenticator when Sign In is clicked.
const menuBarEl = document.getElementById("menu-bar")!;
menuBarEl.appendChild(AccountMenuBar(authApi));

onAuthChange(authApi, (user) => {
  document.getElementById("signInMessage")!.style.display = user == null ? "" : "none";
});

// ─── App (shown when authenticated) ─────────────────────────────────────────
document.getElementById("app")!.appendChild(
  AuthenticatedContent(authApi, (user) => {
    const container = document.createElement("div");
    let question = "";
    let answer = "";
    async function load() {
      answer = await api.askAi(question);
      redraw();
    }

    function redraw() {
      render(
        html`
          <div style="display:flex;gap:8px;margin-bottom:12px">
            <input
              id="question"
              type="text"
              placeholder="AWSについて質問してください"
              style="flex:1"
              @keydown=${(e: KeyboardEvent) => {
                if (e.key === "Enter") {
                  askAi();
                }
              }}
            />

            <button @click=${askAi}>質問</button>
          </div>

          <div
            style="
            border:1px solid #ddd;
            padding:12px;
            border-radius:8px;
            min-height:120px;
          "
          >
            ${answer || "ここに回答が表示されます"}
          </div>
        `,
        container
      );
    }

    async function askAi() {
      const input = container.querySelector("#question") as HTMLInputElement;
      if (!input.value.trim()) {
        return;
      }
      answer = "回答生成中...";
      redraw();
      answer = await api.askAi(input.value);
      redraw();
    }

    load();
    return container;
  })
);


 

  • aws-blocks/index.ts:生成AIチャットボットのバックエンド
    このコードでは、AWS Blocks の Building Block を利用して認証機能と生成AI連携を実装しています。
    認証は AuthBasic、AI機能は Agent として定義されており、複雑なAWSサービスの設定を意識する必要がありません。
    また、ApiNamespace で定義したAPIはフロントエンドから型安全に呼び出すことができます。
    ローカル環境では自動モックとして動作し、そのままAWS環境へデプロイできる点も特徴です。
/**
 * バックエンド — aws-blocks/index.ts
 *

 * 生成AIチャットボットのバックエンドです。
 * 認証済みユーザーからの質問を受け付け、生成AIによる回答を返却します。
 * AWS Blocks の Building Block を利用して、認証・API・AI連携を実現しています。

 * このファイルでは、API・認証・データモデル・リアルタイム通信チャネルなどを定義します。
 * フロントエンドからは `import { ... } from 'aws-blocks'` の形式で直接利用できます。
 
 * ─── 重要 ───────────────────────────────────────────────────────────────
 * データの永続化にローカルファイル、メモリ配列、ローカルデータベースは使用しないでください。
 * 永続化やその他のクラウド機能には Building Block を利用してください。
 
 * Building Block はローカル環境では自動モックとして動作し、
 * AWSへデプロイする際は追加設定なしでクラウドリソースに置き換わります。
 
 * 利用可能な Block の一覧や使い方については以下を参照してください。
 *   node_modules/@aws-blocks/blocks/README.md
 * ─────────────────────────────────────────────────────────────────────────────
 */

import { ApiNamespace, Scope, AuthBasic } from "@aws-blocks/blocks";
// import { z } from "zod";
import { Agent, BedrockModels } from "@aws-blocks/bb-agent";

const scope = new Scope("my-app");

// ─── Auth ────────────────────────────────────────────────────────────────────
const auth = new AuthBasic(scope, "auth", {
  passwordPolicy: { minLength: 8 },
  crossDomain: process.env.BLOCKS_SANDBOX === "true",
});
export const authApi = auth.createApi();

// ─── Agent ────────────────────────────────────────────────────────────────
const agent = new Agent(scope, "aws-agent", {
  model: {
    deployed: {
      provider: "bedrock",
      modelId: "apac.amazon.nova-lite-v1:0",
    },
  },
  systemPrompt: [
    "あなたはAWSに詳しい技術アシスタントです。",
    "回答は日本語で、初心者にも分かるように簡潔に説明してください。",
    "必要に応じて箇条書きを使ってください。",
  ].join("\n"),
});

// ─── API ─────────────────────────────────────────────────────────────────────
export const api = new ApiNamespace(scope, "api", (context) => ({
  async askAi(question: string): Promise<string> {
    const q = question.trim();
    if (!q) {
      return "質問を入力してください。";
    }
    const user = await auth.getCurrentUser(context);
    if (!user) {
      throw new Error("Unauthorized");
    }
    const result = await agent.stream(q, {
      userId: user.userId,
    });
    const done = await result.complete();
    if (!done.text) {
      return "回答が取得できませんでした";
    }
    return done.text;
  },
}));


 

  • (参考) test/e2e.test.ts生成AIチャットボットのテストコード
    AWS Blocks では、ローカルモック環境を利用して認証やAPIを含めたE2Eテストを実行できます。
    authApi を使ったサインイン/サインアウトの検証や、api.askAi() を通じた生成AI機能のテストを簡単に記述できる点が特徴です。
    実際のフロントエンドと同じAPIを利用してテストできるため、本番に近い形で動作確認を行えます。
/**
* AWS Chat AI アプリのE2E(エンドツーエンド)テストです。

* アプリの起動から質問送信、回答表示までの一連の動作を検証します。

* 実行方法:
*   npm run test:e2e
*/

import { test } from "node:test";
import assert from "node:assert";
import { spawn, type ChildProcess } from "node:child_process";
import { setTimeout } from "node:timers/promises";
import { installCookieJar, isServerRunning } from "@aws-blocks/blocks/utils";

import type { api as ApiType, authApi as AuthApiType } from "aws-blocks";

installCookieJar();

let server: ChildProcess | null = null;
let api: typeof ApiType;
let authApi: typeof AuthApiType;

// ─────────────────────────────────────────────
// Setup
// ─────────────────────────────────────────────

test.before(async () => {
  if (!(await isServerRunning())) {
    server = spawn("npm", ["run", "dev:server"], {
      cwd: process.cwd(),
      stdio: ["ignore", "pipe", "pipe"],
      detached: true,
      env: {
        ...process.env,
        NODE_OPTIONS: "",
      },
    });

    server.unref();

    await setTimeout(2000);
  }

  const mod = await import("aws-blocks");

  api = mod.api;
  authApi = mod.authApi;

  for (let i = 0; i < 30; i++) {
    try {
      await authApi.getAuthState();
      return;
    } catch {
      await setTimeout(1000);
    }
  }

  throw new Error("Dev server did not become ready within 30 seconds");
});

test.after(() => {
  if (server?.pid) {
    try {
      process.kill(-server.pid, "SIGTERM");
    } catch {}
  }
});

// ─────────────────────────────────────────────
// Auth
// ─────────────────────────────────────────────

test("auth: starts signed out", async () => {
  const state = await authApi.getAuthState();

  assert.strictEqual(state.state, "signedOut");
});

test("auth: sign up creates account and signs in", async () => {
  const state = await authApi.setAuthState({
    action: "signUp",
    username: "testuser@example.com",
    password: "TestPass123!",
  });

  assert.strictEqual(state.state, "signedIn");

  assert.strictEqual(state.user?.username, "testuser@example.com");
});

test("auth: unauthenticated access is rejected", async () => {
  await authApi.setAuthState({
    action: "signOut",
  });

  await assert.rejects(() => api.askAi("Lambdaとは?"));

  await authApi.setAuthState({
    action: "signIn",
    username: "testuser@example.com",
    password: "TestPass123!",
  });
});

// ─────────────────────────────────────────────
// AI
// ─────────────────────────────────────────────

test("ai: empty question", async () => {
  const result = await api.askAi("");

  assert.strictEqual(result, "質問を入力してください。");
});

test("ai: answer returned", async () => {
  const result = await api.askAi("Lambdaとは?");

  assert.ok(typeof result === "string");

  assert.ok(result.length > 0);
});

test("ai: response contains text", async () => {
  const result = await api.askAi("Auroraとは?");

  assert.ok(result.trim().length > 0);
});

 

  • (参考)index.html:初期画面
<!DOCTYPE html>
<html lang="en">

  <head>

    <meta charset="UTF-8" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <title>Blocks App</title>

    <style>

      body {

        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

        max-width: 860px;

        margin: 40px auto;

        padding: 20px;

        color: #333;

      }

      h1 {

        margin-bottom: 4px;

      }

      .intro {

        color: #666;

        font-size: 0.9em;

        margin-bottom: 24px;

        line-height: 1.5;

      }

      .intro strong {

        color: #444;

      }

      input,

      textarea,

      select {

        padding: 8px;

        margin: 4px;

        border: 1px solid #ddd;

        border-radius: 4px;

        font-size: 0.95em;

      }

      input[type="text"],

      input[type="email"],

      input[type="password"] {

        min-width: 220px;

      }

      button {

        padding: 8px 16px;

        margin: 4px;

        cursor: pointer;

        border: 1px solid #ddd;

        border-radius: 4px;

        background: #f8f8f8;

        font-size: 0.95em;

      }

      button:hover {

        background: #eee;

      }

      ul {

        padding: 0;

      }

      li {

        list-style: none;

      }

    </style>

  </head>

  <body>

    <div id="menu-bar"></div>

    <h1>AWS相談窓口アプリ</h1>

    <p id="signInMessage">サインインしてください</p>

    <div id="auth"></div>

    <div id="app"></div>

    <script type="module" src="/src/index.ts"></script>

  </body>
</html>

 

ローカル検証

では、作ったアプリで早速ローカルで検証してみたいと思います。

先ほど同様に、npm run devコマンド実行し、ローカルサーバ立ち上げて、ブラウザからアクセスしてみます。

アクセス後の初期画面は想定通りになっていますね!
続けてサインインしてみたいと思います!
サインイン後の画面も問題なさそうです!
では、さっそく生成AIに対して質問してみたいと思います!

生成AIの呼び出し先がローカルモックなため、質問に対しての期待していた返答は返ってきませんでしたが、レスポンス自体は返ってきました。
問題なしとして、ローカル検証終了としたいと思います!

 

デプロイ

AWSアカウントへの接続はaws loginコマンドを使用しました。
本記事では詳細を省きますが、下記の参照リンクを添付しておきます。
https://aws.amazon.com/jp/blogs/security/simplified-developer-access-to-aws-with-aws-login/

 

AWSアカウント接続完了したので、デプロイコマンド実行して、実際にAWSアカウントにデプロイしていきたいと思います!

npm run deploy

順調にデプロイ進んでそう、、、、
デプロイには少し時間かかります。(約10分くらい)

デプロイ完了できました!
早速デプロイ実行結果に出力されているフロントエンドのURLにアクセスしてみましょう!

本番にデプロイしたリソースで、おなじように質問したところ、しっかり期待した返答が返ってきました!
(返答内容の出力文字形式が整形はできていませんが、ご容赦ください)

質問文のリクエスト先が実在するBedrockのモデルに向いたことで、レスポンス文が実際の応答に変化することが確認できましたね。
これで、簡易的なチャットボットアプリの完成です!
私の方で試した開発としては、以上で終了です。

※Bedrockモデル選定時の注意点
今回の検証では、aws-blocks/index.ts内でBedrockのモデルを指定しています。
AWS Bedrockで利用できる生成AIモデルは、リージョンやAWSアカウントによって異なります。
サンプルコードやドキュメントで紹介されているモデルでも、利用する環境では使用できない場合があります。
実際に私はモデル選定でつまずいたため、開発を始める前にBedrockコンソールで利用可能なモデル一覧を確認しておくことをおすすめします。
特にAnthropic Claudeなど一部のモデルは、Marketplaceサブスクリプションが必要な場合があります。

※作成した後はリソース削除も忘れずに!(下記コマンドで丸ごと削除できます)

npm run destroy

 

実際に使ってみた所感

開発初心者の私でも、実際に手を動かしていた時間は2時間程度で、簡単な生成AIチャットボットを作成できました。
実際にAWS Blocksを触ってみて、特に以下のような利点を感じました。
 

ローカル検証によるコスト抑制

AWS Blocksにはローカルモック環境が用意されており、実際のAWSリソースを作成しなくてもアプリの動作確認ができます。

開発初期はコード修正と検証を何度も繰り返すため、都度AWSへデプロイせずに済む点は大きなメリットです。

利用料金を気にすることなく試行錯誤できるため、個人学習や技術検証との相性も良いと感じました。

 

反復動作しやすい

実装後すぐに動作確認できるため、思いついたアイデアを素早く試せます。
エラーが発生しても修正結果をすぐ確認できるので、開発サイクルを短く回せます。
特に開発経験が少ない場合でも、「作る→試す→直す」の流れがスムーズで、学習しながら開発を進めやすい印象でした。

 

サービス構成を考えなくていい

通常のAWS開発では、LambdaやDynamoDB、認証基盤など複数のサービスを組み合わせて設計する必要があります。
AWS Blocksでは、アプリケーションコードを中心に開発を進めるだけで、必要なインフラが自動的に構築されます。
そのため、AWSの知識が十分でなくても開発を始めやすく、アプリの機能実装に集中できます。

 

AWS Blocksは、AWSのインフラ構成を意識せずにアプリ開発へ集中できるため、初心者でも短時間で形にしやすい開発フレームワークだと感じました。

 

今後の展望

今回はAWS Blocksの基本的な機能を中心に検証を行いましたが、今後はAIエージェントと組み合わせた開発にも挑戦してみたいと考えています。

AWS Summitのセッションでは、AIエージェントが活用しやすいフレームワークの特徴として、
「ドキュメントがまとまっていること」「コンパイル時に型のフィードバックが得られること」「ローカルで素早く反復開発できること」などが紹介されていました。
今回実際にAWS Blocksを触ってみて、これらの特徴が確かに備わっていることを実感できました。

特に興味を持ったのが Agent Steering の仕組みです。
AWS Blocksでは各BlockにSteering Fileが用意されており、プロジェクト内の AGENT.md に設計方針や実装ルール、利用目的などを記載できます。
AIエージェントはその内容を参照しながら開発を進めるため、毎回チャットで前提条件を説明しなくても、
プロジェクトの意図を理解した状態でコード生成や修正を行えます。
AWS Blocksでは、インストールした時点でこのようなエージェント開発向けの仕組みが組み込まれている点は非常に魅力的だと感じました。

今回の検証ではAIエージェント機能までは利用しませんでしたが、
今後はKiroのような高速なコーディングエージェントとAWS Blocksを組み合わせてみたいと考えています。
Kiroがコード生成や修正を高速に行い、AWS Blocksが認証やデータストア、APIなどのAWSマネージドサービスを抽象化して提供することで、
開発者はサービス構成やインフラ実装を意識することなくアプリケーション開発に集中できます。
AIエージェントによる実装速度と、AWS Blocksによるインフラ自動化が組み合わされば、
短期間で高品質なアプリケーションを構築できるのではないかと期待しています。

 

AWS Blocksはアプリ開発を簡単にするだけでなく、AIエージェントとの協調開発を前提とした次世代の開発スタイルを体験できるフレームワーク!!

 

まとめ

AWS Blocksは、アプリケーションコードを中心に開発を進めながら、必要なAWSインフラを自動的に構築できる新しい開発フレームワークです。

ローカルモックによる高速な検証、End-to-Endの型安全性、CDKを活用したデプロイ、そしてAIエージェントとの協調開発を見据えた設計など、
従来のAWS開発とは異なる新しい開発体験を提供してくれます。

今回私は、開発経験が豊富とは言えない状態からAWS相談窓口チャットボットを作成してみましたが、実際に手を動かしていた時間は2時間程度でした。
特にインフラ構成を意識することなく、アプリケーション開発そのものに集中できた点は非常に印象的でした。

また、AWS BlocksにはAgent SteeringをはじめとしたAIエージェントとの協調開発を支援する仕組みが組み込まれており、
今後はKiroなどのコーディングエージェントと組み合わせることで、さらに開発効率を高められる可能性を感じています。
AIエージェントによる高速な実装と、AWS Blocksによるマネージドサービスの抽象化が組み合わされば、
これまで以上に短期間でアプリケーションを形にできると期待しています。

 

おわりに

AWS Summit 2026で初めてAWS Blocksを知り、「本当に簡単にアプリが作れるのだろうか?」という軽い興味から検証を始めましたが、
想像以上に開発体験の良さを実感できました。

まだパブリックプレビュー段階のサービスですが、「まずは動くものを作ってみたい方」や「インフラ構築よりもアプリケーション開発に集中したい方」
そして「AIエージェントと協調した次世代の開発スタイルに興味がある方」には、ぜひ一度触ってみていただきたいサービスです。

本記事がAWS Blocksに興味を持つきっかけや、これから検証を始める方の参考になれば幸いです。

最後までお読みいただき、ありがとうございました。

×
タイトルとURLをコピーしました