私は同じ機能を探していました。SpoonMeiserが示唆したようにネストされたスタックを使用することは思い浮かびましたが、実際に必要なのはカスタム関数であることがわかりました。幸いなことに、CloudFormationはAWS :: CloudFormation :: CustomResourceの使用を許可します。これにより、少し作業を行うだけで、それを実行できます。これは単なる変数(私が第一にCloudFormationにあるべきだと主張するもの)に対してはやり過ぎのように感じますが、仕事は完了し、さらに(python / nodeを選んでください)のすべての柔軟性を可能にします/ java)。ラムダ関数には費用がかかることに注意してください。しかし、スタックを1時間に複数回作成/削除しない限り、ここでは少額の費用がかかります。
最初のステップは、このページでラムダ関数を作成し、入力値を取得して出力にコピーするだけです。ラムダ関数にあらゆる種類のクレイジーな処理を実行させることもできますが、アイデンティティ関数を取得したら、それ以外は簡単です。または、スタック自体にラムダ関数を作成することもできます。1つのアカウントで多くのスタックを使用しているため、残りのラムダ関数とロールがたくさんあります(ロール--capabilities=CAPABILITY_IAM
も必要なので、すべてのスタックはで作成する必要があります。
ラムダ関数を作成する
- ラムダホームページに移動し、お気に入りの地域を選択します
- テンプレートとして「Blank Function」を選択します
- [次へ]をクリックします(トリガーを構成しないでください)。
- 埋める:
- 名前:CloudFormationIdentity
- 説明:取得したものを返します。CloudFormationの変数サポート
- ランタイム:python2.7
- コード入力タイプ:コードのインライン編集
- コード:以下を参照
- ハンドラ:
index.handler
- 役割:カスタム役割を作成します。この時点で、新しいロールを作成できるポップアップが開きます。このページのすべてを受け入れ、「許可」をクリックします。cloudwatchログに投稿する権限を持つロールを作成します。
- メモリー:128(これは最小値です)
- タイムアウト:3秒(十分なはずです)
- VPC:VPCなし
次に、コードフィールドに以下のコードをコピーして貼り付けます。関数の上部はcfn-response python moduleのコードです。これは、何らかの奇妙な理由で、ラムダ関数がCloudFormationを介して作成された場合にのみ自動インストールされます。このhandler
関数はかなり一目瞭然です。
from __future__ import print_function
import json
try:
from urllib2 import HTTPError, build_opener, HTTPHandler, Request
except ImportError:
from urllib.error import HTTPError
from urllib.request import build_opener, HTTPHandler, Request
SUCCESS = "SUCCESS"
FAILED = "FAILED"
def send(event, context, response_status, reason=None, response_data=None, physical_resource_id=None):
response_data = response_data or {}
response_body = json.dumps(
{
'Status': response_status,
'Reason': reason or "See the details in CloudWatch Log Stream: " + context.log_stream_name,
'PhysicalResourceId': physical_resource_id or context.log_stream_name,
'StackId': event['StackId'],
'RequestId': event['RequestId'],
'LogicalResourceId': event['LogicalResourceId'],
'Data': response_data
}
)
if event["ResponseURL"] == "http://pre-signed-S3-url-for-response":
print("Would send back the following values to Cloud Formation:")
print(response_data)
return
opener = build_opener(HTTPHandler)
request = Request(event['ResponseURL'], data=response_body)
request.add_header('Content-Type', '')
request.add_header('Content-Length', len(response_body))
request.get_method = lambda: 'PUT'
try:
response = opener.open(request)
print("Status code: {}".format(response.getcode()))
print("Status message: {}".format(response.msg))
return True
except HTTPError as exc:
print("Failed executing HTTP request: {}".format(exc.code))
return False
def handler(event, context):
responseData = event['ResourceProperties']
send(event, context, SUCCESS, None, responseData, "CustomResourcePhysicalID")
- 「次へ」をクリックします
- 「関数の作成」をクリックします
[テスト]ボタンを選択してラムダ関数をテストし、サンプルテンプレートとして[CloudFormation Create Request]を選択できるようになりました。ログに送られた変数が返されていることがわかります。
CloudFormationテンプレートで変数を使用する
このラムダ関数ができたので、CloudFormationテンプレートで使用できます。まず、ラムダ関数Arnを書き留めます(ラムダホームページに移動し、作成したばかりの関数をクリックします。Arnは右上にあるはずarn:aws:lambda:region:12345:function:CloudFormationIdentity
です。
テンプレートのリソースセクションで、次のように変数を指定します。
Identity:
Type: "Custom::Variable"
Properties:
ServiceToken: "arn:aws:lambda:region:12345:function:CloudFormationIdentity"
Arn: "arn:aws:lambda:region:12345:function:CloudFormationIdentity"
ClientBucketVar:
Type: "Custom::Variable"
Properties:
ServiceToken: !GetAtt [Identity, Arn]
Name: !Join ["-", [my-client-bucket, !Ref ClientName]]
Arn: !Join [":", [arn, aws, s3, "", "", !Join ["-", [my-client-bucket, !Ref ClientName]]]]
ClientBackupBucketVar:
Type: "Custom::Variable"
Properties:
ServiceToken: !GetAtt [Identity, Arn]
Name: !Join ["-", [my-client-bucket, !Ref ClientName, backup]]
Arn: !Join [":", [arn, aws, s3, "", "", !Join ["-", [my-client-bucket, !Ref ClientName, backup]]]]
まずIdentity
、ラムダ関数のArnを含む変数を指定します。これをここの変数に入れると、一度指定するだけで済みます。typeのすべての変数を作成しますCustom::Variable
。CloudFormationを使用するとCustom::
、カスタムリソースで始まる任意のタイプ名を使用できます。
Identity
変数には、ラムダ関数のArnが2回含まれていることに注意してください。使用するラムダ関数を1回指定します。2回目は変数の値として。
今、私が持っているIdentity
変数を、私が使用して新しい変数を定義することができますServiceToken: !GetAtt [Identity, Arn]
(私はJSONコードのようなものであるべきだと思います"ServiceToken": {"Fn::GetAtt": ["Identity", "Arn"]}
)。それぞれ2つのフィールドを持つ2つの新しい変数を作成します:NameとArn。私のテンプレートの残りの部分では私が使用することができます!GetAtt [ClientBucketVar, Name]
か!GetAtt [ClientBucketVar, Arn]
私はそれを必要なとき。
注意事項
CloudFormationは(クラッシュした)関数からの応答を1時間待機してから放棄するため、カスタムリソースで作業しているときにラムダ関数がクラッシュすると、1〜2時間スタックします。したがって、ラムダ関数の開発中にスタックの短いタイムアウトを指定することをお勧めします。