CaptainDriftwood
CaptainDriftwood

Reputation: 5708

How to add AssetCode to to a CfnFunction class

I am wanting to be able to create a CfnFunction, but be able to pass in an AssetCode class for the code parameter. Normally, using the higher level Function construct provided by aws_cdk.aws_lambda, this would suffice:

class MyFunction(Stack):
    def __init__(self, scope, id, **kwargs):
        super().__init__(scope, id, **kwargs)

        self._python_function = Function(
            self,
            id="PythonFunction",
            runtime=Runtime.PYTHON_3_9,
            handler="app.main.lambda_handler",
            timeout=Duration.minutes(3),
            code=Code.from_asset(
                path="/path/to/my/function",
                bundling=BundlingOptions(
                    image=Runtime.PYTHON_3_9.bundling_image,
                    command=[
                        "bash",
                        "-c",
                        "pip install -r requirements.txt -t /asset-output && cp -au . /asset-output",
                    ],
                ),
            ),
            memory_size=128,
            log_retention=RetentionDays.TWO_WEEKS,
        )

However, when trying to do that using the lower level CfnFunction construct, the documentation does not provide a clear example on how to pass in an AssetCode type:

class MyFunctionWrapper(Stack):

    def __init__(
            self,
            scope,
            id,
            **kwargs,

    ):
        super().__init__(scope, id, **kwargs)

        code_asset: AssetCode = Code.from_asset(
            path="path/to/my/code",
            bundling=BundlingOptions(
                image=Runtime.PYTHON_3_9.bundling_image,
                command=[
                    "bash",
                    "-c",
                    "pip install -r requirements.txt -t /asset-output && cp -au . /asset-output",
                ],
            ),
        )

        self._role = Role(
            self,
            id=f"{id}FunctionRole",
            managed_policies=[
                ManagedPolicy.from_managed_policy_arn(
                    self,
                    id="PolicyArn",
                    managed_policy_arn="arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
                )
            ],
            assumed_by=ServicePrincipal("lambda.amazonaws.com"),
        )

        self._function = CfnFunction(
            self,
            id="Function",
            runtime="PYTHON_3_9",
            handler="app.handler",
            timeout=60,
            memory_size=128,
            role=self._role.role_name,
            code=code_asset,  # <- This is incorrect type for CfnFunction
        )

        self._log_group = LogGroup(
            self,
            id=f"{id}LogGroup",
            log_group_name=f"/aws/lambda/{self._function.function_name}",
            retention=RetentionDays.FIVE_DAYS,
        )


Upvotes: 1

Views: 339

Answers (1)

kichik
kichik

Reputation: 34704

I'm not sure why you would choose to use CfnFunction over Function, but you can check out the source code and see what it does. It passes the bucket and key through code after binding. Translated to Python it should look something like:

bound_code = code_asset.bind(self)

self._function = CfnFunction(
    self,
    id="Function",
    runtime="PYTHON_3_9",
    handler="app.handler",
    timeout=60,
    memory_size=128,
    role=self._role.role_name,
    code=CfnFunction.CodeProperty(
        s3_bucket=bound_code.s3_location.bucket_name,
        s3_key=bound_code.s3_location.object_key,
        s3_object_version=bound_code.s3_location.object_version,
    ),
)

Upvotes: 1

Related Questions