Saya mencari fungsi yang sama. Menggunakan tumpukan bersarang seperti yang disarankan SpoonMeiser muncul di benak, tetapi kemudian saya menyadari bahwa apa yang sebenarnya saya butuhkan adalah fungsi khusus. Untungnya CloudFormation memungkinkan penggunaan AWS :: CloudFormation :: CustomResource yang, dengan sedikit kerja, memungkinkan seseorang untuk melakukan hal itu. Ini terasa seperti berlebihan untuk variabel-variabel yang adil (sesuatu yang saya berpendapat bahwa seharusnya ada di CloudFormation di tempat pertama), tetapi itu menyelesaikan pekerjaan, dan, di samping itu, memungkinkan untuk semua fleksibilitas (pilihlah Anda python / node /Jawa). Perlu dicatat bahwa fungsi lambda membutuhkan biaya, tetapi kami berbicara tentang uang di sini kecuali jika Anda membuat / menghapus tumpukan Anda beberapa kali per jam.
Langkah pertama adalah membuat fungsi lambda pada halaman ini yang tidak melakukan apa-apa selain mengambil nilai input dan menyalinnya ke output. Kita bisa meminta fungsi lambda melakukan semua hal gila, tetapi begitu kita memiliki fungsi identitas, hal lain mudah. Atau kita bisa membuat fungsi lambda dibuat di stack itu sendiri. Karena saya menggunakan banyak tumpukan dalam 1 akun, saya akan memiliki banyak fungsi dan peran lambda yang tersisa (dan semua tumpukan harus dibuat dengan --capabilities=CAPABILITY_IAM
, karena juga membutuhkan peran.
Buat fungsi lambda
- Buka beranda lambda , dan pilih wilayah favorit Anda
- Pilih "Fungsi Kosong" sebagai templat
- Klik "Selanjutnya" (jangan konfigurasikan pemicu apa pun)
- Mengisi:
- Nama: CloudFormationIdentity
- Deskripsi: Mengembalikan apa yang didapatnya, dukungan variabel dalam Formasi Cloud
- Runtime: python2.7
- Jenis Entri Kode: Edit Inline Kode
- Kode: lihat di bawah
- Handler:
index.handler
- Peran: Buat Peran Kustom. Pada titik ini sembulan terbuka yang memungkinkan Anda untuk membuat peran baru. Terima semua yang ada di halaman ini dan klik "Izinkan". Ini akan membuat peran dengan izin untuk memposting ke log cloudwatch.
- Memori: 128 (ini adalah minimum)
- Batas waktu: 3 detik (harus banyak)
- VPC: Tidak ada VPC
Kemudian salin dan tempel kode di bawah ini di bidang kode. Bagian atas fungsi adalah kode dari modul python cfn-response , yang hanya diinstal secara otomatis jika fungsi lambda dibuat melalui CloudFormation, untuk beberapa alasan aneh. The handler
fungsi cukup jelas.
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")
- Klik "Selanjutnya"
- Klik "Buat Fungsi"
Anda sekarang dapat menguji fungsi lambda dengan memilih tombol "Test", dan pilih "CloudFormation Create Request" sebagai templat contoh. Anda harus melihat dalam log Anda bahwa variabel yang dimasukkan ke dalamnya, dikembalikan.
Gunakan variabel dalam templat CloudFormation Anda
Sekarang kita memiliki fungsi lambda ini, kita dapat menggunakannya dalam templat CloudFormation. Pertama-tama catat fungsi lambda Arn (buka halaman lambda , klik fungsi yang baru saja dibuat, Arn harus berada di kanan atas, kira-kira seperti arn:aws:lambda:region:12345:function:CloudFormationIdentity
).
Sekarang di templat Anda, di bagian sumber daya, tentukan variabel Anda seperti:
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]]]]
Pertama saya tentukan Identity
variabel yang berisi Arn untuk fungsi lambda. Menempatkan ini dalam variabel di sini, berarti saya hanya perlu menentukannya sekali. Saya membuat semua variabel tipe saya Custom::Variable
. CloudFormation memungkinkan Anda menggunakan nama jenis apa pun yang dimulai dengan Custom::
sumber daya khusus.
Perhatikan bahwa Identity
variabel berisi Arn untuk fungsi lambda dua kali. Sekali untuk menentukan fungsi lambda untuk digunakan. Kedua kalinya sebagai nilai variabel.
Sekarang saya memiliki Identity
variabel, saya dapat mendefinisikan variabel baru menggunakan ServiceToken: !GetAtt [Identity, Arn]
(saya pikir kode JSON harus seperti "ServiceToken": {"Fn::GetAtt": ["Identity", "Arn"]}
). Saya membuat 2 variabel baru, masing-masing dengan 2 bidang: Nama dan Arn. Di sisa template saya, saya dapat menggunakan !GetAtt [ClientBucketVar, Name]
atau !GetAtt [ClientBucketVar, Arn]
kapan pun saya membutuhkannya.
Kata hati-hati
Saat bekerja dengan sumber daya khusus, jika fungsi lambda macet, Anda mandek antara 1 dan 2 jam, karena CloudFormation menunggu balasan dari fungsi (macet) selama satu jam sebelum menyerah. Oleh karena itu mungkin baik untuk menentukan batas waktu singkat untuk tumpukan sambil mengembangkan fungsi lambda Anda.