您可以以编程方式获取cdk资源的ARN或物理名称吗?

时间:2020-03-03 00:14:51

标签: python amazon-web-services devops aws-cdk

my_project.my_stack.py

from aws_cdk import core
from aws_cdk.aws_s3 import Bucket


class MyStack(core.Stack):
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        self.s3_bucket = Bucket(self, "s3-bucket-id")

app.py

from aws_cdk import core

from my_project.my_stack import MyStack

app = core.App()
my_stack = MyStack(app, "my-stack")

app.synth()

if __name__ == "__main__":
    import boto3
    s3 = boto3.resource('s3')
    bucket = s3.Bucket(my_stack.s3_bucket.bucket_name)
    # ^ raises -- AttributeError: 's3.ServiceResource' object has no attribute 'bucket_name'

运行python app.py会引发 AttributeError:'s3.ServiceResource'对象没有属性'bucket_name'

1 个答案:

答案 0 :(得分:2)

aws-cdk实例化一个代表资源的类时,它不一定已被部署。 s3_bucket.bucket_name的值是一个令牌,表示存储桶名称字符串,供其他cloudformation资源参考。部署后,在非CDK应用程序中获取存储桶名称的最佳方法是将该值存储在可以从您的应用程序访问的位置。

这可以是使用CfnOutput或SSM参数的cloudformation输出值。您可以执行以下操作:

from aws_cdk import core
from aws_cdk.aws_s3 import Bucket
from aws_cdk.aws_ssm import StringParameter


class MyStack(core.Stack):
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        self.s3_bucket_name_param_name = "my-parameter-name"
        self.s3_bucket = Bucket(self, "s3-bucket-id")
        StringParameter(self, "s3-bucket-name-param",
            parameter_name=self.s3_bucket_name_param,
            string_value=self.s3_bucket.bucket_name)

然后从ssm获取参数值。或者,您可以仅静态命名存储桶并引用存储桶名称字符串而不是参数名称。

已经尝试过在应用程序运行时透明地引用资源的想法,punchcard是最著名的示例,但目前仅在CDK的上下文中理解标记化的构造值应用。