Aynı işlevselliği arıyordum. SpoonMeiser'ın önerdiği gibi iç içe bir yığın kullanmak akla geldi, ama sonra gerçekten ihtiyacım olan şeyin özel işlevler olduğunu fark ettim. Neyse ki CloudFormation, AWS :: CloudFormation :: CustomResource'un kullanımına izin verir, bu da biraz çalışma ile birinin bunu yapmasına izin verir. Bu, sadece değişkenler için aşırıya kaçma gibi geliyor (ilk başta CloudFormation'da olması gerektiğini iddia ettiğim bir şey), ancak işi hallediyor ve ek olarak, tüm esnekliklere izin veriyor (python / düğüm seçiminizi yapın / java). Lamda işlevlerinin paraya mal olduğu unutulmamalıdır, ancak yığınlarınızı saatte birkaç kez oluşturmadığınız / silmediğiniz sürece burada kuruşlardan bahsediyoruz.
İlk adım, bu sayfada giriş değerini alıp çıktıya kopyalamaktan başka bir şey yapmayan bir lambda işlevi yapmaktır . Lambda fonksiyonunun her türlü çılgın şeyi yapmasını sağlayabilirdik, ancak kimlik fonksiyonuna sahip olduktan sonra, başka her şey kolaydır. Alternatif olarak, yığının kendisinde lambda işlevi yaratılabilir. 1 hesapta birçok yığın kullandığımdan, bir sürü artık lambda işlevi ve rolüne sahip olacağım (ve tüm rollerin birlikte oluşturulması gerekiyor --capabilities=CAPABILITY_IAM
, çünkü bir role de ihtiyacı var.
Lambda işlevi oluştur
- Lambda ana sayfasına gidin ve en sevdiğiniz bölgeyi seçin
- Şablon olarak "Boş İşlev" i seçin
- "İleri" yi tıklayın (tetikleyici yapılandırmayın)
- Doldurun:
- İsim: CloudFormationIdentity
- Açıklama: Bulut Formation'da aldığı şeyi, değişken desteği döndürür
- Oynatma Süresi: python2.7
- Kod Giriş Türü: Kod Satırını Düzenle
- Kod: aşağıya bakın
- işleyici:
index.handler
- Rol: Özel bir Rol oluşturun. Bu noktada, yeni bir rol oluşturmanıza izin veren bir açılır pencere açılır. Bu sayfadaki her şeyi kabul edin ve "İzin Ver" i tıklayın. Bulut izleme günlüklerine gönderme izinleriyle bir rol oluşturacaktır.
- Bellek: 128 (bu minimumdur)
- Zaman aşımı: 3 saniye (bol olmalıdır)
- VPC: VPC yok
Ardından aşağıdaki kodu kod alanına kopyalayıp yapıştırın. İşlevin üst kısmı, sadece garip bir nedenden ötürü lambda işlevi CloudFormation aracılığıyla oluşturulduğunda otomatik olarak kurulan cfn-yanıt python modülünün kodudur. handler
Fonksiyon yeterince açıklayıcı olduğunu.
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")
- Sonrakine tıkla"
- "İşlev Oluştur" u tıklayın
Artık lambda işlevini "Test" düğmesini seçip örnek şablon olarak "CloudFormation Create Request" i seçerek test edebilirsiniz. Günlüğünüzde kendisine beslenen değişkenlerin döndürüldüğünü görmelisiniz.
CloudFormation şablonunuzda değişken kullanın
Artık bu lambda fonksiyonuna sahip olduğumuza göre, bunu CloudFormation şablonlarında kullanabiliriz. Önce lambda işlevi Arn'ı not edin ( lambda ana sayfasına gidin, yeni oluşturulan işlevi tıklayın, Arn sağ üstte olmalı, gibi bir şey arn:aws:lambda:region:12345:function:CloudFormationIdentity
).
Şimdi şablonunuzda, kaynak bölümünde aşağıdaki gibi değişkenlerinizi belirtin:
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]]]]
Önce Identity
lambda işlevi için Arn içeren bir değişken belirtiyorum. Bunu bir değişkene buraya koymak, onu sadece bir kez belirtmem gerektiği anlamına gelir. Tüm değişkenlerimi tür haline getiriyorum Custom::Variable
. CloudFormation, Custom::
özel kaynaklar için ile başlayan herhangi bir tür adını kullanmanızı sağlar .
Not Identity
değişken iki kez lambda fonksiyonu için Arn içerir. Bir kez kullanılacak lambda işlevini belirtin. Değişkenin değeri olarak ikinci kez.
Şimdi Identity
değişken var, ben ServiceToken: !GetAtt [Identity, Arn]
(JSON kodu gibi bir şey olması gerektiğini düşünüyorum) kullanarak yeni değişkenler tanımlayabilirsiniz "ServiceToken": {"Fn::GetAtt": ["Identity", "Arn"]}
. Her biri 2 alana sahip 2 yeni değişken oluşturuyorum: Name ve Arn. Şablonumun geri kalanında kullanabileceğim !GetAtt [ClientBucketVar, Name]
ya !GetAtt [ClientBucketVar, Arn]
ben İhtiyacınız olduğunda.
Dikkat kelimesi
Özel kaynaklarla çalışırken, lambda işlevi çökerse, 1 ile 2 saat arasında sıkışıp kalırsınız, çünkü CloudFormation (çöktü) işlevinden vazgeçmeden önce bir saat boyunca yanıt bekler. Bu nedenle, lambda işlevinizi geliştirirken yığın için kısa bir zaman aşımı belirtmek iyi olabilir.