Apakah ada cara untuk mendefinisikan pintasan untuk nilai yang sering digunakan yang berasal dari parameter template CloudFormation?
Sebagai contoh - Saya punya skrip yang membuat tumpukan Proyek Multi-AZ dengan nama ELB project
dan dua contoh di belakang ELB yang dipanggil project-1
dan project-2
. Saya hanya meneruskan ELBHostName
parameter ke template dan kemudian menggunakannya untuk membangun:
"Fn::Join": [
".", [
{ "Fn::Join": [ "", [ { "Ref": "ELBHostName" }, "-1" ] ] },
{ "Ref": "EnvironmentVersioned" },
{ "Ref": "HostedZone" }
]
]
Konstruksi ini atau sangat mirip diulang berkali-kali di seluruh templat - untuk membuat nama host EC2, catatan Route53, dll.
Alih-alih mengulangi itu berulang-ulang saya ingin menetapkan output itu Fn::Join
ke variabel semacam dan hanya merujuk itu, sama seperti saya bisa dengan "Ref":
pernyataan.
Idealnya seperti:
Var::HostNameFull = "Fn::Join": [ ... ]
...
{ "Name": { "Ref": "Var::HostNameFull" } }
atau sesuatu yang serupa sederhana.
Apakah itu mungkin dengan Amazon CloudFormation?
Jawaban:
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
index.handler
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.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:
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 sayaCustom::Variable
. CloudFormation memungkinkan Anda menggunakan nama jenis apa pun yang dimulai denganCustom::
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 menggunakanServiceToken: !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.
sumber
cloudformation-tool
permata), jadi saya kemas kreasi lambda ke dalam templat dan kemudian dapat menggunakannya secara langsung alih-alih membuatIdentity
sumber daya khusus. Lihat di sini untuk kode saya: gist.github.com/guss77/2471e8789a644cac96992c4102936fb3Saya tidak punya jawaban, tetapi ingin menunjukkan bahwa Anda dapat menyelamatkan diri dari banyak rasa sakit dengan menggunakannya
Fn::Sub
sebagai gantinyaFn::Join
Menggantikan
sumber
Tidak. Saya mencobanya, tetapi kosong. Cara yang masuk akal bagi saya adalah membuat entri pemetaan yang disebut "CustomVariables" dan memiliki semua variabel saya di rumah itu. Ini berfungsi untuk Strings sederhana, tetapi Anda tidak dapat menggunakan Intrinsics (Refs, Fn :: Joins, etc.) di dalam Mappings .
Bekerja:
Tidak akan bekerja:
Itu hanya sebuah contoh. Anda tidak akan menempatkan Ref mandiri dalam Variabel.
sumber
Anda bisa menggunakan stack bersarang yang menyelesaikan semua variabel Anda di output itu, dan kemudian gunakan
Fn::GetAtt
untuk membaca output dari tumpukan itusumber
Anda mungkin menggunakan templat bersarang tempat Anda "menyelesaikan" semua variabel di templat luar dan meneruskannya ke templat lain.
sumber