

AwsCustomResourceのonUpdateでonCreateの物理IDを直接使う方法
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
AwsCustomResourceでonCreateのレスポンスから物理IDを取得して、それをonUpdateのSDKコールパラメータにそのまま使いたい場面があった。最初は「別々のAwsCustomResourceに分けてgetResponseField()で受け渡すしかない」と思ってたけど、実はCDKに専用のクラスが用意されてた。
結論
custom_resources.PhysicalResourceIdReferenceをonUpdate(やonDelete)のパラメータ値としてそのまま渡せば、そのカスタムリソースが持ってる現在の物理IDに実行時解決される。physicalResourceIdをPhysicalResourceId.fromResponse()で設定していても、PhysicalResourceId.of()の固定値でも同じ仕組みで参照できる。
何が問題だったか
AwsCustomResourceはonCreate・onUpdate・onDeleteをひとつのリソースにまとめて書ける。それぞれのphysicalResourceIdは基本同じ値を指定するし、CloudFormationがリソースを識別するために使う。
ただ、onCreateで作ったリソースのIDをonUpdateのAPIパラメータ(リソース名やARNなど)としてそのまま使いたい時、physicalResourceId: PhysicalResourceId.fromResponse('ResourceId')のように書いても、その値をonUpdate.parametersの中に直接埋め込む方法がないように見えた。
実際の書き方
const resource = new custom_resources.AwsCustomResource(this, 'MyResource', { onCreate: { service: 'SomeService', action: 'createSomething', parameters: { Name: 'example-resource', }, physicalResourceId: custom_resources.PhysicalResourceId.fromResponse('ResourceId'), }, onUpdate: { service: 'SomeService', action: 'updateSomething', parameters: { ResourceId: new custom_resources.PhysicalResourceIdReference(), }, }, policy: custom_resources.AwsCustomResourcePolicy.fromSdkCalls({ resources: custom_resources.AwsCustomResourcePolicy.ANY_RESOURCE, }),});ResourceIdの値としてnew custom_resources.PhysicalResourceIdReference()を渡すだけ。実行時にそのカスタムリソースの物理IDに置き換わる。
getResponseField()との違いは役割にある。getResponseField()はAPIレスポンスの値をCDKアプリの外(他リソースのプロパティなど)に渡すためのもの。PhysicalResourceIdReferenceは同じAwsCustomResourceの中で、CloudFormationが管理してる物理IDを次のSDKコールにそのまま渡すためのもの。用途が違う。
未確認
fromResponse()で取得したパスがParameter.ARNのような階層構造の場合でも同じように解決されるかは実機で試してない。ドキュメント上は物理ID自体を参照する仕組みなので問題なさそうだけど、そこは要確認。