Tôi đã tìm kiếm các chức năng tương tự. Sử dụng một ngăn xếp lồng nhau như SpoonMeiser gợi ý đã xuất hiện, nhưng sau đó tôi nhận ra rằng điều tôi thực sự cần là các chức năng tùy chỉnh. May mắn thay, CloudFormation cho phép sử dụng AWS :: CloudFormation :: CustomResource , với một chút công việc, cho phép một người làm điều đó. Cảm giác này giống như quá mức cho các biến số (thứ mà tôi cho rằng đáng lẽ phải có trong CloudFormation ở nơi đầu tiên), nhưng nó đã hoàn thành công việc, và, ngoài ra, cho phép tất cả sự linh hoạt của (chọn lựa python / nút / java). Cần lưu ý rằng các hàm lambda tốn tiền, nhưng chúng ta đang nói về đồng xu ở đây trừ khi bạn tạo / xóa ngăn xếp của mình nhiều lần mỗi giờ.
Bước đầu tiên là tạo một hàm lambda trên trang này mà không làm gì ngoài việc lấy giá trị đầu vào và sao chép nó vào đầu ra. Chúng ta có thể có chức năng lambda làm tất cả các loại công cụ điên rồ, nhưng một khi chúng ta có chức năng nhận dạng, mọi thứ khác đều dễ dàng. Ngoài ra, chúng ta có thể có chức năng lambda được tạo trong ngăn xếp. Vì tôi sử dụng nhiều ngăn xếp trong 1 tài khoản, tôi sẽ có cả đống chức năng và vai trò lambda còn sót lại (và tất cả các ngăn xếp cần phải được tạo ra --capabilities=CAPABILITY_IAM
, vì nó cũng cần một vai trò.
Tạo chức năng lambda
- Tới trang chủ lambda và chọn khu vực yêu thích của bạn
- Chọn "Hàm trống" làm mẫu
- Nhấp vào "Tiếp theo" (không định cấu hình bất kỳ kích hoạt nào)
- Điền vào:
- Tên: CloudFormationIdentity
- Mô tả: Trả về những gì nó nhận được, hỗ trợ biến trong Cloud Formation
- Thời gian chạy: python2.7
- Loại nhập mã: Chỉnh sửa nội tuyến mã
- Mã: xem bên dưới
- Xử lý:
index.handler
- Vai trò: Tạo Vai trò Tùy chỉnh. Tại thời điểm này, một cửa sổ bật lên mở ra cho phép bạn tạo một vai trò mới. Chấp nhận mọi thứ trên trang này và nhấp vào "Cho phép". Nó sẽ tạo ra một vai trò với quyền để đăng lên nhật ký đám mây.
- Bộ nhớ: 128 (đây là mức tối thiểu)
- Thời gian chờ: 3 giây (nên có nhiều)
- VPC: Không có VPC
Sau đó sao chép-dán mã dưới đây trong trường mã. Phần trên cùng của hàm là mã từ mô-đun python phản hồi cfn , chỉ được cài đặt tự động nếu chức năng lambda được tạo thông qua CloudFormation, vì một số lý do lạ. Các handler
chức năng là khá tự giải thích.
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")
- Nhấn tiếp"
- Nhấp vào "Tạo chức năng"
Bây giờ bạn có thể kiểm tra chức năng lambda bằng cách chọn nút "Kiểm tra" và chọn "Yêu cầu tạo CloudFormation" làm mẫu mẫu. Bạn sẽ thấy trong nhật ký của mình rằng các biến được cung cấp cho nó, được trả về.
Sử dụng biến trong mẫu CloudFormation của bạn
Bây giờ chúng ta có chức năng lambda này, chúng ta có thể sử dụng nó trong các mẫu CloudFormation. Trước tiên hãy ghi chú chức năng lambda Arn (đi đến trang chủ lambda , nhấp vào chức năng vừa tạo, Arn phải ở trên cùng bên phải, đại loại như thế arn:aws:lambda:region:12345:function:CloudFormationIdentity
).
Bây giờ trong mẫu của bạn, trong phần tài nguyên, chỉ định các biến của bạn như:
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]]]]
Đầu tiên tôi chỉ định một Identity
biến chứa Arn cho hàm lambda. Đặt cái này vào một biến ở đây, có nghĩa là tôi chỉ phải xác định nó một lần. Tôi thực hiện tất cả các biến của tôi về loại Custom::Variable
. CloudFormation cho phép bạn sử dụng bất kỳ tên loại nào bắt đầu bằng Custom::
tài nguyên tùy chỉnh.
Lưu ý rằng Identity
biến chứa Arn cho hàm lambda hai lần. Một lần để xác định chức năng lambda để sử dụng. Lần thứ hai là giá trị của biến.
Bây giờ tôi có Identity
biến, tôi có thể định nghĩa các biến mới bằng cách sử dụng ServiceToken: !GetAtt [Identity, Arn]
(Tôi nghĩ mã JSON phải giống như vậy "ServiceToken": {"Fn::GetAtt": ["Identity", "Arn"]}
). Tôi tạo 2 biến mới, mỗi biến có 2 trường: Tên và Arn. Trong phần còn lại của mẫu tôi có thể sử dụng !GetAtt [ClientBucketVar, Name]
hoặc !GetAtt [ClientBucketVar, Arn]
bất cứ khi nào tôi cần.
Lời cảnh báo
Khi làm việc với tài nguyên tùy chỉnh, nếu chức năng lambda gặp sự cố, bạn sẽ bị kẹt trong khoảng từ 1 đến 2 giờ, vì CloudFormation chờ phản hồi từ chức năng (bị sập) trong một giờ trước khi bỏ cuộc. Do đó, có thể tốt khi chỉ định thời gian chờ ngắn cho ngăn xếp trong khi phát triển chức năng lambda của bạn.