Возвращайте данные из CDK пользовательского ресурса с поддержкой Лямбды

#python #amazon-web-services #amazon-cloudformation #aws-cdk

Вопрос:

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

 from typing_extensions import runtime
import os
from aws_cdk import (
    core as cdk, aws_iam as iam, aws_lambda as lamb, aws_route53 as route53, aws_logs as logs,
    custom_resources as cr
)

import builtins

from jsii import python


class hz_with_delegation(cdk.Construct):
    def __init__(self, scope: cdk.Construct, id: builtins.str, delSet: builtins.str, env: builtins.str) -> builtins.any:
        super().__init__(scope, id)

        self.hostedZoneLambdaRole = iam.Role(
            self, "hzlambdarole", assumed_by=iam.ServicePrincipal('lambda.amazonaws.com'))
        self.hostedZoneLambdaRole.add_to_policy(
            iam.PolicyStatement(resources=["*"], actions=["route53:*"])
        )

        self.hzResourceLambda = lamb.Function(self, "hz_custom_resource_handler",
                                              runtime=lamb.Runtime.PYTHON_3_8,
                                              handler="main.on_event",
                                              role=self.hostedZoneLambdaRole,
                                              code=lamb.Code.from_asset(
                                                  os.path.dirname(__file__)   "/lambda"),
                                              log_retention=logs.RetentionDays.ONE_DAY
                                              )

        self.hz_with_delegation_provider = cr.Provider(self, "hz_with_delegation_set",
                                                       on_event_handler=self.hzResourceLambda,

                                                       )
        self.cr = cdk.CustomResource(self, "hz_with_delegation",
                                     service_token=self.hz_with_delegation_provider.service_token,
                                     properties={
                                         "delSet": delSet,
                                         "env": env
                                     })

 

Я не могу понять, как получить какую-либо информацию от этого лоха, как только она будет получена

 class CdkPoCStack(cdk.Stack):

    def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        
# Custom resource to handle the delegation

        test = custom_hosted_zone.hz_with_delegation(
            self, id="some Id", delSet="N06079012Q8954F8DG91Y", env=environment)

 

В конечном счете, мне нужен физический идентификатор ресурса, и я собираюсь передать его обратно в лямбду поставщика в поле данных ответа. Чтобы получить данные, мне нужно выполнить getAttr, для этого мне нужен логический идентификатор

Ни за что на свете я не могу понять, как получить физический или, что более важно, логический идентификатор пользовательской конструкции ресурса.

Я попробовал это

 self.get_logical_id(test)
 

и я получаю эту ошибку

 Traceback (most recent call last):
  File "/Users/sahm.samarghandi/bbot/CDK_PoC/app.py", line 16, in <module>
    CdkPoCStack(app, "DjangoAppStack",
  File "/Users/sahm.samarghandi/bbot/CDK_PoC/.venv/lib/python3.9/site-packages/jsii/_runtime.py", line 83, in __call__
    inst = super().__call__(*args, **kwargs)
  File "/Users/sahm.samarghandi/bbot/CDK_PoC/cdk_poc/cdk_poc_stack.py", line 35, in __init__
    print(self.get_logical_id(test.cr))
  File "/Users/sahm.samarghandi/bbot/CDK_PoC/.venv/lib/python3.9/site-packages/aws_cdk/core/__init__.py", line 15945, in get_logical_id
    return typing.cast(builtins.str, jsii.invoke(self, "getLogicalId", [element]))
  File "/Users/sahm.samarghandi/bbot/CDK_PoC/.venv/lib/python3.9/site-packages/jsii/_kernel/__init__.py", line 128, in wrapped
    return _recursize_dereference(kernel, fn(kernel, *args, **kwargs))
  File "/Users/sahm.samarghandi/bbot/CDK_PoC/.venv/lib/python3.9/site-packages/jsii/_kernel/__init__.py", line 340, in invoke
    response = self.provider.invoke(
  File "/Users/sahm.samarghandi/bbot/CDK_PoC/.venv/lib/python3.9/site-packages/jsii/_kernel/providers/process.py", line 359, in invoke
    return self._process.send(request, InvokeResponse)
  File "/Users/sahm.samarghandi/bbot/CDK_PoC/.venv/lib/python3.9/site-packages/jsii/_kernel/providers/process.py", line 326, in send
    raise JSIIError(resp.error) from JavaScriptError(resp.stack)
jsii.errors.JSIIError: Object of type @aws-cdk/core.CustomResource is not convertible to @aws-cdk/core.CfnElement
 

Ответ №1:

Согласно документации, вы должны иметь возможность получить физический идентификатор, используя атрибут ref пользовательского ресурса.

Однако, если вам нужен логический идентификатор, вам нужно будет использовать defaultChild атрибут node создаваемого вами пользовательского ресурса (поскольку вы используете конструкцию второго уровня). Как только вы получите этот дочерний элемент по умолчанию, вы сможете получить логический идентификатор из id атрибута.