Вызов API / веб-запрос от CloudFormation - PullRequest
1 голос
/ 14 марта 2019

Я хочу вызвать конечную точку API REST в конце моего шаблона CloudFormation.

PUT https://example.com/v1/endpoint
{
  // Body Content
}

Есть ли способ сделать это?Я могу думать только так:

  1. Создание лямбда-функции
  2. Выполнение лямбда-функции с помощью CF
  3. Удаление функции лямбды

Вышеуказанный подход кажется очень грязным и требует больше усилий, чем необходимо.

1 Ответ

3 голосов
/ 14 марта 2019

Вы ищете пользовательских ресурсов .Это ресурс, который обрабатывается лямбда-функцией.Эта функция не должна создавать какой-либо фактический ресурс.Это может просто назвать вашу конечную точку.Если вы определите функцию Lambda как часть вашего стека, она будет удалена при удалении стека.

Функция Lambda получает что-то вроде следующего:

{
   "RequestType" : "Create",
   "ResponseURL" : "http://pre-signed-S3-url-for-response",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/stack-name/guid",
   "RequestId" : "unique id for this create request",
   "ResourceType" : "Custom::TestResource",
   "LogicalResourceId" : "MyTestResource",
   "ResourceProperties" : {
      "Name" : "Value",
      "List" : [ "1", "2", "3" ]
   }
}

и требует отправкичто-то вроде следующего к URL в ResponseURL:

{
   "Status" : "SUCCESS",
   "PhysicalResourceId" : "TestResource1",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/stack-name/guid",
   "RequestId" : "unique id for this create request",
   "LogicalResourceId" : "MyTestResource",
   "Data" : {
      "OutputName1" : "Value1",
      "OutputName2" : "Value2",
   }
}

Чтобы упростить это, лямбда-функции имеют доступ к cfnresponse , который реализует код ответа.

Вот полный пример:

Resources:
  CustomFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile: |
          import cfnresponse
          from botocore.vendored import requests
          def handler(event, context):
            if event["RequestType"] in ["Create", "Update"]:
              requests.put("https://example.com/v1/endpoint", {})
            elif event["RequestType"] == "Delete":
              pass  # if you want to do something on delete, do it here
            cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, "ok")
      Handler: index.handler
      Role: !GetAtt CustomFunctionRole.Arn
      Runtime: python3.6
  CustomFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
  Custom:
    Type: Custom::Something
    Properties:
      ServiceToken: !GetAtt CustomFunction.Arn

Вы должны обработать исключения в своем коде и использовать cfnresponse.send(event, context, cfnresponse.FAILED, {}, "ok"), чтобы CloudFormation не просто сидела и ждала чего-то.Время ожидания может занять некоторое время.

...