amazon-web-services - aws cdk Fn.import_value 返回 token 忽略bucketname 的cloudformation 输出并显示 token

标签 amazon-web-services amazon-s3 aws-cloudformation aws-cdk aws-cdk-context

成功“cdk 部署 CdkS3Stack”后,输出以及 cdk 输出会在 CloudFormationConsole 中正确显示。

from aws_cdk import (
    Stack,
    aws_s3 as _s3,
    CfnOutput
)

from constructs import Construct

class CdkS3Stack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        bucket_proto = _s3.Bucket(self, id = "protoBucket",
            block_public_access=_s3.BlockPublicAccess.BLOCK_ALL,
            encryption=_s3.BucketEncryption.S3_MANAGED,
            versioned=False
        )

        bucket_json = _s3.Bucket(self, id = "jsonBucket",
            block_public_access = _s3.BlockPublicAccess.BLOCK_ALL,
            encryption=_s3.BucketEncryption.S3_MANAGED,
            versioned=False
        )

        # #Output of created resource
        CfnOutput(scope=self, id='PROTOBUCKETNAME',
                        value=bucket_proto.bucket_name)
        CfnOutput(scope=self, id='PROTOBUCKETARN',
                        value=bucket_proto.bucket_arn)
        CfnOutput(scope=self, id='JSONBUCKETNAME',
                        value=bucket_json.bucket_name)
        CfnOutput(scope=self, id='JSONBUCKETARN',
                        value=bucket_json.bucket_arn)

**但是,当我尝试访问输出时,我在正确获取输入方面遇到问题。尽管输出在 cloudformation 控制台和命令行输出中正确显示,但打印语句显示如下。

protobucket ${Token[TOKEN.255]}
jsonbucket ${Token[TOKEN.256]}    
protobucketarn ${Token[TOKEN.257]}

最后,下面的堆栈在部署阶段“cdk deploy CdkLambdaStack”失败,并出现错误“未找到名为 PROTOBUCKETARN 的导出”。 我们尝试使用 lambda 堆栈中的 Fn.import_value 获取上述输入的代码是:

CdkLambdaStack: creating CloudFormation changeset...
CdkLambdaStack | 0/10 | 1:50:25 AM | UPDATE_IN_PROGRESS   | AWS::CloudFormation::Stack    | CdkLambdaStack User Initiated
CdkLambdaStack | 0/10 | 1:50:28 AM | UPDATE_ROLLBACK_IN_P | AWS::CloudFormation::Stack    | CdkLambdaStack No export named PROTOBUCKETARN foundCdkLambdaStack | 1/10 | 1:50:33 AM | UPDATE_ROLLBACK_COMP | AWS::CloudFormation::Stack    | CdkLambdaStack 
CdkLambdaStack | 2/10 | 1:50:33 AM | UPDATE_ROLLBACK_COMP | AWS::CloudFormation::Stack    | CdkLambdaStack 
from aws_cdk import (
   Stack,
   aws_lambda as _lambda,
   aws_iam as _iam,
   Fn,
   aws_s3 as _s3,
   aws_s3_notifications as _s3n
   #CfnOutput
)

from constructs import Construct

class CdkLambdaStack(Stack):

   def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
       super().__init__(scope, construct_id, **kwargs)
       #Create role for your Lambda function
       lambda_role = _iam.Role(scope=self, id='cdk-lambda-role',
                               assumed_by =_iam.ServicePrincipal('lambda.amazonaws.com'),
                               role_name='cdk-lambda-role',
                               managed_policies=[
                               _iam.ManagedPolicy.from_aws_managed_policy_name(
                                   'AWSLambda_FullAccess'),
                               _iam.ManagedPolicy.from_aws_managed_policy_name(
                                   'CloudWatchFullAccess'),
                               _iam.ManagedPolicy.from_aws_managed_policy_name(
                                   'AmazonS3FullAccess')    
                               ])

       lambdaLayer = _lambda.LayerVersion(self, 'lambda-layer',
                 code = _lambda.AssetCode('./cdk_lambda_stack/lambda/layer/'),
                 compatible_runtimes = [_lambda.Runtime.PYTHON_3_9],
       )          
       
       proto_bucket = Fn.import_value("PROTOBUCKETNAME")     <----
       json_bucket = Fn.import_value("JSONBUCKETNAME")       <----
       proto_bucket_arn = Fn.import_value("PROTOBUCKETARN")   <----

       print("protobucket", proto_bucket)
       print("jsonbucket", json_bucket)
       print("protobucketarn", proto_bucket_arn)
       # Defines an AWS Lambda resource
       cdk_lambda = _lambda.Function(
           self, 'cdk-lambda-func',
           runtime=_lambda.Runtime.PYTHON_3_9,
           function_name='cdk-lambda-function',
           description='Lambda function deployed using AWS CDK Python',
           code=_lambda.Code.from_asset('./cdk_lambda_stack/lambda/code'),
           handler='my_lambda_code.lambda_handler',
           role=lambda_role,
           layers = [lambdaLayer],
           environment={
               'NAME': 'cdk-lambda-function-env',
               'PROTO_BUCKET': proto_bucket,
               'JSON_BUCKET': json_bucket
           }
       )
       proto_bucket_ref = _s3.Bucket.from_bucket_arn(self, id = "protoBucket-abc",
             bucket_arn = proto_bucket_arn)              <------
       proto_bucket_ref.add_event_notification(_s3.EventType.OBJECT_CREATED,
             _s3n.LambdaDestination(cdk_lambda))    <-------

我做错了什么??????输出应该在那里并且可以看到。如果我注释掉箭头指示的行(即 lambda 堆栈中的跨堆栈引用)来读取输出,则不会出现错误。

最佳答案

输出应该使用export_name和Fn完成。import_value应该使用export_name在另一个堆栈中完成:

堆栈 1:

CfnOutput(scope=self, id='PROTOBUCKETNAME',export_name="ProtoBuf:BucketName",description="protobuf 存储桶名称", value=bucket_proto.bucket_name)

堆栈 2:

proto_bucket_name = Fn.import_value("ProtoBuf:BucketName")

关于amazon-web-services - aws cdk Fn.import_value 返回 token 忽略bucketname 的cloudformation 输出并显示 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73603588/

相关文章:

amazon-web-services - 无法上传 HelloWorldFunction 资源的 CodeUri 参数引用的工件 None

java - 将 AWS SageMaker 机器学习模型转换为 Java 库

java - 保证在 AWS lambda 退出之前运行函数

aws-cloudformation - cdk : Importing the output of an unrelated different stack

amazon-web-services - 如何通过 CloudFormation 为 lambda 函数配置 Alexa Skills Kit 触发器?

amazon-web-services - 禁止从私有(private)注册表访问的 AWS EB docker-compose 部署

amazon-web-services - 创建 S3 存储桶策略时出错 - 属性 PolicyDocument 的值必须是对象

java - 有没有办法使用分段上传(Java 高级 API)使用 "java.util.zip"将提取的 zip 文件上传到 AWS-S3

amazon-web-services - 通过 IP 限制对 S3 存储桶的访问而不影响 IAM 凭证

amazon-web-services - docker pull <image> 无法在 cloudformation UserData 标签中工作