CloudFormation の Fn::GetStackOutput が正式リリース - 制約事項を検証してみた

CloudFormation の Fn::GetStackOutput が正式リリース - 制約事項を検証してみた

CloudFormation の Fn::GetStackOutput が正式リリースされました。公式ドキュメントで明記された Known limitations(Fn::Sub 変数マップ内や Outputs 直接値での使用不可など)を実際に確認し、エラー挙動と回避策、CDK の新コンテキストキーによる移行方法を整理します。
2026.05.15

2026年5月14日、AWS 公式ブログで Fn::GetStackOutput の正式リリースが発表されました。

https://aws.amazon.com/jp/blogs/devops/simplify-cross-account-and-cross-region-stack-output-references-with-aws-cloudformation-and-cdks-new-fngetstackoutput/

先行2記事では、CDK の PR から確認できた Fn::GetStackOutput の挙動をベースに、クロスリージョン参照とクロスアカウント参照を検証しています。

https://dev.classmethod.jp/articles/cloudformation-fn-getstackoutput-cross-region-reference/

https://dev.classmethod.jp/articles/cloudformation-fn-getstackoutput-cross-account-reference/

この記事では、正式リリースに伴って公式ドキュメントに追加された制約事項と、CDK の新しいコンテキストキーを中心に整理します。基本構文やクロスリージョン・クロスアカウント参照の検証手順は上記の先行記事で扱っているため、差分に絞ります。

正式リリースの概要

CloudFormation Template Reference に公式ドキュメントが掲載されています。

https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-getstackoutput.html

CloudFormation がサポートされている全リージョンで利用可能です。公式サポートされた機能として本番環境での採用を検討できるようになりましたが、後述する Known limitations と弱参照(依存なし)の性質は理解が必要です。

動作確認環境

項目 バージョン
検証実施日 2026-05-15
検証リージョン ap-northeast-1, us-east-1
AWS CLI 2.34.39
aws-cdk-lib 2.254.0
CDK CLI 2.1122.0

過去記事との差分サマリ

公式ドキュメントと照合した範囲では、過去記事で紹介した構文、IAM 設定、弱参照の挙動はおおむね整合していました。新たに判明した情報は、Known limitations(使えない場所)、引数や配置箇所の詳細、ショートハンド記法の制約、Error handling の詳細、CDK の @aws-cdk/core:defaultCrossStackReferences コンテキストキーです。

Known limitations

公式ドキュメントで未サポートとされているパターンです。手元の検証では、いずれも CreateChangeSet の時点で InternalFailure になりました。

パターン 公式ドキュメント上の扱い 検証結果
Fn::Sub の変数マップ値内 未サポート InternalFailure
Fn::Base64 未サポート InternalFailure
Outputs セクションの直接値 未サポート InternalFailure
Conditions セクションの Fn::Equals 未サポート InternalFailure
Fn::ImportValue 未サポート InternalFailure

公式ドキュメントでは、将来的なサポートが言及されています("Support for these patterns will be added in a future update")。

検証結果の詳細

手元の検証では、全5パターンとも CreateChangeSet の時点で失敗しました。Change Set の実行やリソース作成までは到達しないため、リソース作成途中でロールバックするケースではありません。

手元の環境では、以下のエラーになりました。

An error occurred (InternalFailure) when calling the CreateChangeSet operation (reached max retries: 2): Unknown

reached max retries: 2 は AWS CLI 側のリトライ回数に関する表示です。本質的なエラーは InternalFailure / Unknown です。ValidationError ではなく InternalFailure であり、どの制約に引っかかったかの情報が出ないため、事前に把握していないと原因特定に時間がかかる可能性があります。

検証に使用したテンプレート

代表例として、Fn::Sub の変数マップ値内と Outputs セクションの直接値を掲載します。

Fn::Sub の変数マップ値内(NG)
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  Param:
    Type: AWS::SSM::Parameter
    Properties:
      Name: /getstackoutput-test/sub-test
      Type: String
      Value:
        Fn::Sub:
          - "prefix-${Val}-suffix"
          - Val:
              Fn::GetStackOutput:
                StackName: getstackoutput-producer
                OutputName: MyValue
Outputs セクションの直接値(NG)
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  Dummy:
    Type: AWS::CloudFormation::WaitConditionHandle

Outputs:
  Chained:
    Value:
      Fn::GetStackOutput:
        StackName: getstackoutput-producer
        OutputName: MyValue

回避策:Fn::Join で代替する

Fn::Sub の変数マップ値内で使えないケースは、リソースプロパティ内であれば Fn::Join で代替できる場合があります。

# ❌ NG:Fn::Sub の変数マップ値内
Value:
  Fn::Sub:
    - "arn:aws:s3:::${BucketName}"
    - BucketName:
        Fn::GetStackOutput:
          StackName: getstackoutput-producer
          OutputName: BucketName

# ✅ OK:Fn::Join で代替
Value:
  Fn::Join:
    - ""
    - - "arn:aws:s3:::"
      - Fn::GetStackOutput:
          StackName: getstackoutput-producer
          OutputName: BucketName

ただし、Outputs セクションや Fn::ImportValue 内の制約は Fn::Join で回避できるものではありません。あくまでリソースプロパティ内で文字列を組み立てたいケースでの代替手段です。

実際に Fn::Join 内で動作することを確認しました。

Fn::Join 内での使用(OK)— 検証テンプレート
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  Param:
    Type: AWS::SSM::Parameter
    Properties:
      Name: /getstackoutput-test/join-workaround
      Type: String
      Value:
        Fn::Join:
          - ""
          - - "prefix-"
            - Fn::GetStackOutput:
                StackName: getstackoutput-producer
                OutputName: MyValue
            - "-suffix"

Outputs:
  JoinedValue:
    Value: !GetAtt Param.Value
OutputKey:   JoinedValue
OutputValue: prefix-hello-from-ap-northeast-1-suffix

Fn::Join 内で Fn::GetStackOutput が解決され、期待どおりの値になりました。

Fn::GetStackOutput 自体を配置できる場所

公式ドキュメントでは、以下の位置で Fn::GetStackOutput を使用できるとされています。

  • リソースプロパティの直接値 ✅
  • Fn::Join 内 ✅
  • Fn::If 内 ✅
  • Fn::Select 内 ✅

Fn::If 内での使用

Conditions セクションの Fn::Equals 内は NG ですが、リソースプロパティの Fn::If 内は OK です。この境界は誤解しやすいため、実際に確認しました。

Fn::If 内での使用(OK)— 検証テンプレート
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  UseRemoteStack:
    Type: String
    Default: "true"
    AllowedValues: ["true", "false"]

Conditions:
  UseRemote: !Equals [!Ref UseRemoteStack, "true"]

Resources:
  Param:
    Type: AWS::SSM::Parameter
    Properties:
      Name: /getstackoutput-test/if-test
      Type: String
      Value:
        Fn::If:
          - UseRemote
          - Fn::GetStackOutput:
              StackName: getstackoutput-producer
              OutputName: MyValue
          - "local-fallback"

Outputs:
  ResolvedValue:
    Value: !GetAtt Param.Value
OutputKey:   ResolvedValue
OutputValue: hello-from-ap-northeast-1

UseRemote 条件が真の場合に Fn::GetStackOutput が解決され、偽の場合はフォールバック値が使われます。

Fn::GetStackOutput の引数に指定できる関数

StackNameRoleArn など各パラメータ値には、以下の関数を指定できます。

  • Ref
  • Fn::Sub
  • Fn::If
  • Fn::Join
  • Fn::Select
  • Fn::FindInMap
  • Fn::Base64

ただし、リソースに依存する値(例:!GetAtt SomeBucket.Arn)は指定できません。各パラメータはデプロイ前に解決される必要があるためです。

ショートハンド記法の制約と実際の挙動

公式ドキュメントの Important 注記には以下の記載があります(原文):

You can't use the short form of !GetStackOutput when it contains other short form functions such as !Sub or !Ref as parameter values. In that case, use the full function name.

つまり、以下のような書き方は避けるべきとされています。

# 公式ドキュメントの Important では避けるべきと読める書き方
Value: !GetStackOutput
  StackName: !Ref MyStackNameParam
  OutputName: VpcId

代わりに、完全記法を使います。

# 公式の注意事項に沿った書き方(完全記法)
Value:
  Fn::GetStackOutput:
    StackName: !Ref MyStackNameParam
    OutputName: VpcId

検証結果

手元の検証では、公式ドキュメントの Important と実挙動に差があるように見えました。!GetStackOutput 内に !Ref を指定したテンプレートはデプロイに成功し、値も正しく解決されました。

検証に使用したテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  ProducerStackName:
    Type: String
    Default: getstackoutput-producer

Resources:
  Param:
    Type: AWS::SSM::Parameter
    Properties:
      Name: /getstackoutput-test/shorthand-ng
      Type: String
      Value: !GetStackOutput
        StackName: !Ref ProducerStackName
        OutputName: MyValue
$ aws cloudformation deploy --stack-name test-shorthand-ng --template-file test-shorthand-ng.yaml
Successfully created/updated stack - test-shorthand-ng

SSM パラメータの値も hello-from-ap-northeast-1 が正しく格納されていました。

ただし、公式ドキュメントの注意事項に反する書き方が現時点で動作する挙動に依存するのは避けた方が安全です。将来の実装変更で挙動が変わる可能性もあるため、公式ドキュメントの注意事項に沿って完全記法を使うのが無難です。

Error handling

公式ドキュメントに記載されたエラーパターンです。このセクションは公式ドキュメントの記載に基づく整理であり、個別のエラーはこの記事では追加検証していません。

状況 エラー
IAM ロールを Assume できない アクセス拒否エラー
DescribeStacks 権限がない アクセス拒否エラー
参照先スタックが存在しない ValidationError
指定した OutputName が存在しない ValidationError
参照先リージョンが有効化されていない 失敗
無効なリージョン ValidationError

us-east-1 と opt-in リージョン間の注意事項

公式ドキュメントの Error handling セクションには、us-east-1 と opt-in リージョン間で参照する場合にエラーが発生する可能性がある旨が記載されています。これは Fn::GetStackOutput 固有の問題ではなく、STS トークンのリージョン互換性に関する注意事項です。

該当する場合は以下の公式ドキュメントを参照してください。

https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html

この記事では未検証です(opt-in リージョン未有効化のため)。

CDK の新コンテキストキー @aws-cdk/core:defaultCrossStackReferences

公式ブログで、CDK のクロスリージョン・クロスアカウント参照の挙動を制御する新しいコンテキストキーが紹介されました。

同一アカウント・同一リージョン 同一アカウント・クロスリージョン クロスアカウント
strong(デフォルト) Fn::ImportValue ExportWriter/ExportReader(従来のカスタムリソース) weak にフォールバック(公式ブログ記載)
both Fn::GetStackOutput + Export Fn::GetStackOutput + ExportWriter(ExportReader なし) Fn::GetStackOutput + IAM ロール
weak Fn::GetStackOutput Fn::GetStackOutput Fn::GetStackOutput + IAM ロール

上記の表は公式ブログの説明に基づく整理です。手元で cdk synth を確認したのは同一アカウントのクロスリージョン参照のみです。クロスアカウント構成での synth / deploy はこの記事では未検証です。

cdk synth 結果の比較

クロスリージョン参照(同一アカウント、ap-northeast-1 → us-east-1)で cdk synth した結果です。

モード Producer 側 Consumer 側
weak VPC のみ(カスタムリソースなし) Fn::GetStackOutput で直接参照
strong ExportWriter(Lambda + IAM Role)生成 ExportReader(Lambda + IAM Role + SSM)生成
both ExportWriter(Lambda + IAM Role)が残る Fn::GetStackOutput で直接参照(ExportReader なし

both の意味

both は、Consumer 側の参照を Fn::GetStackOutput に切り替えつつ、Producer 側には既存 Consumer 向けの Export または ExportWriter を残す移行用モードです。

手元で確認したクロスリージョン参照では、Producer 側に ExportWriter が残り、Consumer 側の ExportReader は生成されませんでした。

cdk.json 設定例

{
  "context": {
    "@aws-cdk/core:defaultCrossStackReferences": "weak"
  }
}

動作確認バージョン

  • aws-cdk-lib: 2.254.0
  • CDK CLI: 2.1122.0

最小対応バージョンはこの記事では確認していません。少なくとも上記バージョンでは cdk synth 結果を確認済みです。

crossRegionReferences: true からの移行

crossRegionReferences: true を使っている既存プロジェクトの移行パスです。

  1. crossRegionReferences: true を削除し、@aws-cdk/core:defaultCrossStackReferences: "both" を設定
  2. cdk synth で生成テンプレートを確認(Consumer 側は Fn::GetStackOutput に、Producer 側は ExportWriter が残る)
  3. デプロイして動作確認
  4. 安定したら "both""weak" に変更(Producer 側の ExportWriter も削除される想定)

crossRegionReferences: true@aws-cdk/core:defaultCrossStackReferences を併用した場合の挙動はこの記事では未検証です。

まとめ

Fn::GetStackOutput が正式リリースされました。公式ドキュメントで Known limitations が明記されたことで、使える場所と使えない場所の境界が明確になっています。制約違反時は InternalFailure / Unknown でエラー詳細が出ないため、この記事で紹介した制約を把握しておくと原因調査の助けになります。

CDK ユーザーは @aws-cdk/core:defaultCrossStackReferences で参照方式を選択できるようになりました。既存プロジェクトの移行では、both を経由する進め方が有力な選択肢になりそうです。

スタック間に強い依存関係や削除ブロックを求めない用途であれば、Export 宣言もカスタムリソースも不要な Fn::GetStackOutput は有力な選択肢になります。

参考リンク

この記事をシェアする

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

関連記事