2026年8月 Flociアップデートまとめ、CloudFrontの配信とAppSyncのGraphQLエンドポイントが動くようになった

2026年8月 Flociアップデートまとめ、CloudFrontの配信とAppSyncのGraphQLエンドポイントが動くようになった

LocalStack代替のAWSエミュレータFlociの2026年8月分まとめ。1.6.0と1.7.0で入ったCloudFrontの配信と署名付きURL検証、AppSyncのGraphQLエンドポイント、IAMマネージドポリシー、アカウント分離を動かして確認し、リゾルバー未実装やAllow *固定など範囲も整理します。
2026.08.29

こんにちは。サービス開発部の武田です。

LocalStackの代替として登場したオープンソースのAWSエミュレータ「Floci」を、これまでも取り上げてきました。

前回からまた1ヵ月が経ちました。今回もこの1ヵ月の更新を、いくつか手元で動かしながらまとめていきます。

今回はリリースが2回に減った一方で、1.6.0、1.7.0とマイナーバージョンが2つ上がり、1回あたりの中身は大きくなりました。リリース済みの内容とmainブランチの内容、READMEの数字がそれぞれ別のタイミングで動いているので、どの時点の数字かをそろえて読む必要がある月です。前回の宿題にしていたAppSyncと、立てた2つのissueの行方も確認します。

この1ヵ月の主な変化(2026年8月28日時点)

前回記事(1.5.34時点)から現在(1.7.0)までの変化をサマリーすると、次のとおりです。

  • リリース 2回(1.6.0が8月6日、1.7.0が8月18日)。1.5.34から1.7.0までの間に 227コミット
  • 対応サービスの公式表記は、1.7.0タグのREADMEでは 69のまま。8月28日時点のmainでは 82
  • GitHubスターが 18,022 → 22,504
  • READMEの互換性テスト件数は 2,506のまま
  • AppSyncのGraphQLエンドポイントが動くようになった。ただしリゾルバーは動かない
  • CloudFrontがコンテンツを配信するようになった。署名付きURLも検証される
  • IAMがAWSマネージドポリシー1,566件を解決できるようになった。ただし中身はすべてAllow *
  • アカウント間のストレージ分離が修正された
  • 新サービスはMWAA(実Airflow)、CloudWatch RUM、SWF、Managed Service for Apache Flinkなど

順に見ていきます。

リリース版とmainで数字が違う

1.5.34(7月29日)の次が1.6.0(8月6日)、その次が1.7.0(8月18日)で、それ以降は8月28日時点でリリースがありません。6月末から7月前半の3〜4日間隔には戻っていませんが、開発は止まっておらず、1.7.0のあとmainには 160コミットが積まれています。Organizations、Resource Explorer 2、FIS、EFSなどはこの未リリース分に入っています。手元で動かすのは、リリース済みの1.6.0と1.7.0です。

READMEの対応サービス数は、このずれが見える場所です。1.7.0タグのREADMEは前回と同じ「69 AWS services」のままで、同じタグのサービス一覧にはSWFやMWAAの行が増えているのに総数が追随していません。数字が動いたのはリリース後です。

日付 README表記 契機
8月18日(1.7.0) 69 前回から変わらず
8月21日 72 FISの追加に合わせて更新(#2435)
8月23日 73 「MWAAを表に追加し、サービス数を訂正」(#2496)
8月24日 76 一覧から漏れているサービスを検出するチェックの追加(#2465)
8月27日 82 Network Firewall、Route 53 Resolverなどの追加

69から82への差分は、訂正と未リリースの新サービスが混ざったものです。#2465でコードと一覧を突き合わせるチェックが入ったので、この先は一覧の更新漏れは検出しやすくなります。

リリースノートの「新サービス」の数え方にも幅があります。1.6.0の「3つ」に含まれるBedrockは以前から一覧にあり、今回入ったのはOpenAI互換APIへ中継するプロキシです。1.7.0の「9つ」に含まれるTransit GatewayはEC2内の機能です。数字をそのまま足せるものではありません。

互換性テストの件数は、READMEの表が1.5.34、1.7.0、mainのいずれでも2,506件で、内訳まで同じでした。compatibility-testsディレクトリには変更が入っているので、表の数字が据え置きになっているだけで、テストが増えていないとは言い切れません。

前回の宿題

環境構築はこれまでと同じで、docker-compose.ymlを用意して起動します。

services:
  floci:
    image: floci/floci:1.7.0
    ports:
      - "4566:4566"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
$ export AWS_ENDPOINT_URL=http://localhost:4566
$ export AWS_DEFAULT_REGION=us-east-1
$ export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test

AppSync: GraphQLエンドポイントは動くが、リゾルバーは動かない

前回は、GraphQLのエンドポイントにPOSTするとS3のXMLエラーが返ってくる状態でした。当時開いていた「Phase 6: Query Execution + HTTP Endpoint」のPR(#1884)が1.7.0に入りました。リリースノートには「a working GraphQL service that executes queries against real data sources」とあります。

確かめたいのは「リゾルバーが動いてデータソースの値が返るか」です。NONEデータソースに固定のメッセージを返すリゾルバー、DynamoDBデータソースにGetItemのリゾルバーを付けたAPIを作り、クエリを投げました。DynamoDBのテーブルにはアイテムを入れ、データソース用のIAMロールも作成してあります。

$ curl -s "http://localhost:4566/v1/apis/${API_ID}/graphql" \
    -H "Content-Type: application/json" -H "x-api-key: ${API_KEY}" \
    --data '{"query":"query { hello(name: \"Floci\") { message } }"}'
{"data":{"hello":null}}

$ curl -s "http://localhost:4566/v1/apis/${API_ID}/graphql" \
    -H "Content-Type: application/json" -H "x-api-key: ${API_KEY}" \
    --data '{"query":"query { getOrder(pk: \"o-1\") { pk item } }"}'
{"data":{"getOrder":null}}

前回のS3エラーは解消し、GraphQLのレスポンスが返るようになりました。ただし値はどちらもnullで、リゾルバーは動いていません。構文エラーや未定義フィールドはerrorsに入り、introspectionも動くので、エンドポイントとクエリエンジンまでは使える状態です。

これはドキュメントに書かれているとおりです。1.7.0タグのdocs/services/appsync.mdには「Nullable fields may be null until DataFetchers (Phase 8)」とあります。リゾルバーのディスパッチはPhase 8、DynamoDBなどのデータソース接続はPhase 9です。リリースノートには「real data sources」とありますが、1.7.0で使えるのはPhase 6の範囲、つまりHTTPエンドポイントとクエリの解釈までにとどまります。

認証(Phase 7)は8月19日にマージされていますが未リリースです。1.7.0ではx-api-keyなしでも200が返ります。nightlyイメージ(floci/floci:nightly-08272026)で試すとキーなしは401になりました。ところが、create-api-keyで得たidを付けても401でした。生のレスポンスを見ると、idとは別にapiKeyというフィールドがあり、認証で照合されるのはこちらです。

{"apiKeys":[{"id":"e2f514f","apiId":"...","apiKey":"da2-cc88835"}],"nextToken":null}

AWSのApiKeyapiKeyというフィールドはなく、idそのものがda2-で始まるキー値です。CLIやSDKはAPIモデルにないフィールドを捨てるので、このままではSDK経由でAPIキー認証が通りません。idをキー値にするPRを出し(#2645)、その日のうちにマージされています。

#2042: Logs Insightsの>=は「警告付きで無視」に変わった

前回、Logs Insightsのfilterが未対応の構文を静かに無視する件でissueを立てました。likeは全件が返り、>=は0件が返る、というものです。

1.7.0では>=が全件を返すようになり、サーバーログにIgnoring unsupported Logs Insights filter: @message >= "x"という警告が出ます。likestatsと同じ扱いにそろった形です。別の方が出したPR(#2170)で、issueを参照しつつ>=<==~の誤解析を直しています。

issue本体の論点だった「未対応の構文をエラーにすべきか」は、PRの中でも「メンテナの判断に委ねる」として残されていて、issueはopenのままです。

#2043: Cloud Controlは作れるが一覧できない

未対応タイプに空のリストを返す件は、1.7.0でも変わっていません。ListResourcesの対応タイプは6から9に増えました(#2062。後述の#2037に統合してマージ)。

一方で1.7.0ではCreateResourceDeleteResourceGetResourceが入りました(#2037)。CloudFormationのプロビジョナーを流用する作りです。SQSキューで試すと、作成と個別取得はできて、一覧だけ空になります。

$ aws cloudcontrol create-resource --type-name AWS::SQS::Queue --desired-state '{"QueueName":"cc-created"}'
# → GetResourceRequestStatus で SUCCESS
$ aws cloudcontrol get-resource --type-name AWS::SQS::Queue \
    --identifier http://localhost:4566/000000000000/cc-created \
    --query 'ResourceDescription.Properties' --output text
{"QueueName":"cc-created","Id":"http://localhost:4566/000000000000/cc-created"}
$ aws cloudcontrol list-resources --type-name AWS::SQS::Queue --query 'ResourceDescriptions'
[]

作成と個別取得はCloudFormationで扱えるタイプに広く対応し、一覧は9タイプだけ、という対応範囲の差がAPIの間にあります。前回は「未対応タイプ」の話でしたが、同じタイプでも作成と一覧の結果が食い違います。

1.7.0を動かして分かったこと

CloudFrontが配信するようになった

CloudFrontはこれまで、ディストリビューションなどの設定を保存するだけでした。1.7.0で、S3オリジンとカスタムオリジンからの配信(#1820)と、署名付きURLの検証(#1831)が入っています。

S3バケットにindex.htmlを置き、それをオリジンにしたディストリビューションを作ります。ディストリビューションのドメイン名をHostヘッダーに付けて、Flociのポートに直接リクエストします。

$ curl -s -i -H "Host: EE0UZT5JDQPAM1.cloudfront.net" http://localhost:4566/
HTTP/1.1 200 OK
Content-Type: text/html
...

<h1>hello from S3 origin</h1>

S3のオブジェクトが返ってきました。DefaultRootObjectも効いていて、/へのアクセスでindex.htmlが返ります。存在しないキーは404です。

署名付きURLは、RSA鍵ペアの公開鍵とキーグループを登録し、TrustedKeyGroupsを有効にしたビヘイビアで試しました。

アクセス 結果
署名なし 403
aws cloudfront signで作った署名付きURL 200
期限切れの署名付きURL 403

S3のオブジェクトを署名付きURL経由でだけ取り出す構成を、ローカルで通せるようになりました。

範囲には注意点があります。ドキュメントによると、キャッシュポリシーやオリジンリクエストポリシーのデータプレーン評価は未実装で、ビューアのクエリ文字列はオリジンへ転送されません。レスポンスヘッダーもS3のものがそのまま返ります。動くのは「オリジンへのルーティングと署名検証」だと考えておくのがよさそうです。

アカウント間のストレージ分離

Flociはアクセスキーに12桁の数字を使うと、それをアカウントIDとして扱います。1.7.0のリリースノートには、DynamoDBのアイテム(#2240)とS3のオブジェクト本体(#2241)をアカウント間で分離した、という修正が載っています。修正が入ったということは、以前は分離されていなかったはずです。1.5.34と1.7.0で同じ操作をして比べてみました。

アカウント111111111111(A)でordersテーブルを作ってアイテムを1件入れ、アカウント222222222222(B)でも同名のテーブルを作ります。S3でも同様に、同名バケットの同名キーにBから書き込みます。

操作 1.5.34 1.7.0
Bが同名テーブルを作成したあとのAのscan 0件(Aのアイテムが消える) 1件
Bが同名バケット・同名キーにput-objectしたあとのAのget-object Bの内容が返る Aの内容が返る
Bがそのキーをdelete-objectしたあとのAのget-object InternalError Aの内容が返る

1.5.34では、テーブルやバケットの一覧はアカウントごとに分かれているのに、中身は名前で共有されていました。1.7.0ではAの内容が保たれています。

S3のバケット名は実際のAWSではグローバルに一意ですので、S3の行はFlociの内部ストレージの分離を確かめるテストです。AWS互換の確認としては、実際のAWSでもアカウントごとに同名リソースを作れるDynamoDBの行を見てください。確認できたのはこの2サービスの範囲です。

IAMマネージドポリシー: 1,566件のARN解決と権限評価は別

1.7.0で、IAMがAWSマネージドポリシーのカタログをすべてもつようになりました(#2194)。それまでは手書きの59件だけで、それ以外のarn:aws:iam::aws:policy/...NoSuchEntityでした。CDKやTerraformで実在のマネージドポリシーを参照すると失敗する、という問題への対応です。

$ aws iam list-policies --scope AWS --query 'length(Policies)'
1566

実在するARNはアタッチでき、存在しないARNは拒否されます。名前の解決という意味では「full catalog」のとおりです。ただし、ポリシーの中身は別です。

$ aws iam get-policy-version --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
    --version-id v1 --query 'PolicyVersion.Document.Statement'
[{"Effect": "Allow", "Action": "*", "Resource": "*"}]

すべてを許可するドキュメントです。ソースのmanaged-policies.yamlにも「ポリシードキュメントはモデル化していない」と明記されています。Flociはデフォルトではポリシーを評価しないので、全エントリを同じ許可ドキュメントに解決する設計です。

この制約が表面化するのは、前回取り上げたIAM強制モード(FLOCI_SERVICES_IAM_ENFORCEMENT_ENABLED=true、デフォルトは無効)を有効にしたときです。AmazonS3ReadOnlyAccessだけを付けたユーザーで操作してみます。

# ro-user(AmazonS3ReadOnlyAccess のみ)のアクセスキーで実行
$ aws s3 mb s3://ro-made-this
make_bucket: ro-made-this
$ echo written-by-ro | aws s3 cp - s3://root-bucket/y.txt
$ aws sqs create-queue --queue-name ro-q
{
    "QueueUrl": "http://localhost:4566/000000000000/ro-q"
}

読み取り専用のはずのユーザーで、バケットの作成、オブジェクトの書き込み、SQSキューの作成まで成功しました。同じ読み取り権限をs3:Get*s3:List*のインラインポリシーで書いたユーザーでは、CreateBucketPutObjectAccessDeniedになります。インラインポリシーは書いたとおりに評価され、マネージドポリシーはFlociが保持しているAllow *が評価されています。

IaCを通す目的なら1,566件のカタログは役に立ちます。一方で「このロールに付けたマネージドポリシーで足りるか」をローカルで試す用途には使えません。強制モードのドキュメントに注意書きがあるとよさそうです。

その他の更新

手元では確認していませんが、リリースノートに書かれている範囲で目立った変更を挙げます。

分類 内容 バージョン
Lambda Lambda Extensions APIの実装(#1773) 1.6.0
MWAA 実Airflow(LocalExecutor)をバックエンドにしたMWAAの追加(#2086) 1.6.0
Bedrock ConverseをOpenAI互換APIへ中継するプロキシバックエンド(#1789)。InvokeModelはスタブのまま、ストリーミングは501 1.6.0
Cognito リフレッシュトークンをHMAC署名し、期限とプールのスコープを検証(#2132、#2135、#2139) 1.7.0
EKS IRSAへの対応。OIDC発行者とJWT検証を含む(#2108) 1.7.0
CloudFormation AWS::EC2::VPCEndpoint、ネットワークACLなど11タイプの追加。リソース単位のDeletionPolicyConditionGetTemplateSummary 1.7.0
Firehose BufferingHintsの時間・サイズによる書き出し(#2314) 1.7.0
配布 mainからワンボタンでリリースを切るしくみと、ECR Publicへのバージョン付き公開(#2127) 1.6.0

まとめ

この1ヵ月のFlociは、リリースが2回に減った一方で、その2回に227コミットが入り、マイナーバージョンが2つ上がりました。手元で動かして分かったことは次のとおりです。

  • AppSyncはGraphQLのHTTPエンドポイントが動くようになり、前回のS3エラーは解消。ただしリゾルバーは未実装で、設定したリゾルバーは実行されずnullが返る。ドキュメントのとおりPhase 8以降の扱い
  • Logs Insightsの>=の誤解析は別の方のPRで「警告付きで無視」に修正された。未対応構文をエラーにすべきかという本題は残っている
  • Cloud ControlはCreateResourceGetResourceが入り、SQSキューを作って読めるが、同じタイプのListResourcesは空のまま
  • CloudFrontはS3オリジンからの配信と署名付きURLの検証が動く。キャッシュポリシーの評価は未実装
  • 別アカウントの同名テーブル・同名キーで起きていた中身の衝突が1.7.0で解消した
  • IAMマネージドポリシーは1,566件の名前を解決できるが、中身はすべてAllow *。強制モードでは読み取り専用ポリシーのユーザーが書き込める

READMEの対応サービス数は1.7.0タグでは69のままで、mainでは82になっています。リリースノートの「新サービス」の数、READMEの数字、mainの状態はそれぞれ別のタイミングで動くので、どの時点の数字かをそろえて読む必要があります。

気になった点のうち、AppSyncのAPIキーは原因まで追えたのでPRにしました(#2645)。CreateApiKeyが返すidをAWSと同じda2-形式のキー値にして、認証もそのidで照合する修正です。出した日のうちにマージされ、Phase 7と同じく次のリリース待ちです。1.7.0以降にmainへ積まれた160コミット分は、正式リリースに入ってからあらためて確認する予定です。

本記事の数値やリリース内容は、次の一次情報をもとにしています。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事