⛱️

Cfn組み込み関数に登場した「Fn::ForEach」についてcfn-language-discussionを読んで理解してみた。

2023/07/28に公開

Fn::ForEachが登場

2023年7月26日Cloudformarionに新しい組み込み関数「Fn::ForEach」が登場しました。
https://aws.amazon.com/jp/about-aws/whats-new/2023/07/accelerate-cloudformation-authoring-experience-looping-function/

本記事ではこの組み込み関数を理解するにあたり、記事作成時点(※2023年7月28日)公式ドキュメント上にある情報だけでは不十分であると感じ、cfn-language-discussionを一読した要点を抜粋したものになります。


この組み込み関数が出来るまでは

一例ですが、以下のようなものも存在しました。
https://qiita.com/dnpds-murata/items/5c9e507bce2b6dbf695d


現時点で公式ドキュメントと本関数に言及した記事

前提となる本組み込み関数の構文そのものや利用シーンについては主題の意図する所の外としますので、以下にお目通しいただき次章へ進んでいただけますと嬉しいです。

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-foreach.html

https://dev.classmethod.jp/articles/cloudformation-foreach/

https://dev.classmethod.jp/articles/202307-cloudformation-foreach-findinmap-01/


For=Looping?

「ループ」と聞いて思い浮かぶ処理

forと聞くと以下のような処理を想像します。
(個人的に利用する事が多いVBAの例)

Sub sample1()
	Dim i As Integer
	For i = 1 To 5
		MsgBox "こんにちは"
	Next i
End Sub

上から順番に処理し指定した条件になるまで工程をループします。

For Eachの例は以下です。

Sub sample2(
	Dim ws As Worksheet
	For Each ws In Worksheets
		ws.PrintPreview
	Next ws
Ends Sub

配列の中にある要素の数(Length)分ループします。

この組み込み関数が発表された際、その語感から「ループ機能がでた!」という声が当然あり個人的には自分でもうまく説明できないのですがぼんやりした違和感を覚えました。

その理由を考えてみたのですが、

CloudFormationはスタック実行時、裏でリソース間の参照・依存関係を読み取り、あるべき順にリソースが作成されるプログラムが走っています。

例えばVPCとサブネットを作成するテンプレートの場合,
VPCがないとサブネットは作成開始出来ない為、サブネット側には「どのVPCに作るの?」という設定項目が存在し、被参照側が参照側より早く作成されます。

DependsOnという依存関係を設定する事で、明示的に「こっちの方を先に作ってね(こっちが作り終わるまでそっちは走らせないでね)」と指定する事が出来、それ以外は参照・被参照関係に準拠します。

そして、依存関係の発生しないリソース同士はデプロイ速度が早く済むように並列で作成されるものです。

私が持っている先ほどの「ForEachループ」のイメージに当てはまるのであれば、配列から一つずつの要素を携え、他の処理を実行しないままリソースの作成をする動作でありそうですが、上記プログラム的な観点からいって依存関係を暗黙的に発生させて順次(並列ではなく)処理させる(或いは そうしか出来ない)機能という風な想像になりますがそんな動きするかなというのが疑問でした。


名前から受けるイメージ通り順次処理なのか確認してみた

二章目の記事内のSNS Topicを作成する例のコレクション(=配列)に以下を指定して実行しました。

sample1.yml
AWSTemplateFormatVersion: 2010-09-09
Transform: 'AWS::LanguageExtensions'
# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------#
Resources:
  'Fn::ForEach::HogeLoopName':
    - HogeItems
    - [a,b,c,d,e,f,g,h,i,j,k,l]
    - 'Topic${HogeItems}':
        Type: 'AWS::SNS::Topic'
        Properties:
          TopicName: !Ref HogeItems

結果(※topicの後の一文字がコレクションの値と一致)

厳密には上記表示で順序通りでない事を持って、100%裏で0番目の要素から開始の信号が走っていない事を確信しきるものではないですが、答えの無い深読みを避ければ並列処理されているのではといって良さそうです。(暫定的)


組み込み関数のネーミングについて

これらについてはドキュメントから真意は読み取れませんでしたが、Twitter(※現X)上で最初に以下投稿を発見します。

更に冒頭のcfn-language-discussionには以下のように本関数のネーミングに対して複数の選択肢と議論があった旨の記載がありました。


ドキュメントが更新されるまでに意識すべきと思われる部分

説明に添えられたサンプルテンプレートは元ページにありますが、以下はドキュメントから読み取れない制約もあり、今後不足している部分が追加更新されたり、リソース作成失敗時のエラーメッセージが親切な文章に変更されるまでは意識すべき部分です。

出来る事(※2023年7月28日時点)



出来ない事・制約(※2023年7月28日時点)








潜在的なフォローアップに関わる部分については今後「要望が多ければ」追加される機能としてあるものもありますので、積極的に希望を出せば組み込み関数の存在も変わっていくかもしれません。

CloudFormation WorkShopに対応するページが追加

2023年8月22日以下Workshopにページが追加されました。
https://catalog.workshops.aws/cfn101/en-US/intermediate/templates/looping-over-collections

以上でした

お読みいただき有難うございました。

Discussion