【问题标题】:Accessing resources from a stack in a CDK app created in another stack within the same app从同一应用程序的另一个堆栈中创建的 CDK 应用程序中的堆栈访问资源
【发布时间】:2021-03-15 12:07:33
【问题描述】:

我正在使用内部构造库,该库负责创建 ECS 集群和服务以及要运行的任务定义。一切都在其内部发生,在其构造函数中创建所有这些资源后,不会返回任何内容(它只是该库提供的函数调用)。当我调用该函数时,我将我的 App 对象作为该堆栈的范围传递,所以除了我在我的 CDK 代码中创建的堆栈之外,同一个 App 对象包含两个堆栈。

我的观点是为了传递要在我的 lambda 中使用的任务定义的名称(作为参数传递给 RunTask AWS SDK 调用以启动任务),我需要该任务的名称/引用在内部构造库中创建的定义。

我想知道在 AWS CDK 中访问此类资源的最佳方式是什么。使用类成员作为获取器来访问这些资源是否可以,或者ConstructNode 是处理这种情况的正确方法?

【问题讨论】:

    标签: amazon-web-services aws-cdk


    【解决方案1】:

    您可以将属性添加到您的 CDK 堆栈并在其他堆栈中引用这些属性。每个 CloudFormation 堆栈在幕后创建 outputsparameters。 (这可能并不总是理想的,因为我的特定用例使重构和更新应用程序变得更加困难。)

    // Pipeline contains an ECR repository we'd like to reference elsewhere
    public class PipelineStack : Stack
    {
        public IRepository EcrRepository { get; }
    
        public PipelineStack(Construct parent, string id, IPipelineStackProps props)
            : base(parent, id, props)
        {
            EcrRepository = new Repository(
                this,
                "EcrRepository",
                new RepositoryProps
                {
                    // props
                });
    
            // rest of stack...
        }
    }
    
    // Given IApiStackProps similar to:
    public interface IApiStackProps : IStackProps
    {
        IRepository Repository { get; }
    }
    
    // Now we'd like to load an ECR task found in that referenced repository
    public class ApiStack : Stack
    {
        public ApiStack(Construct parent, string id, IApiStackProps props)
            : base(parent, id, props)
        {
            var repo = Repository.FromRepositoryName(
                this,
                "EcrRepository",
                props.Repository.RepositoryName);
    
            var container = new ContainerDefinition(
                this,
                "ApiContainer",
                new ContainerDefinitionProps
                {
                    TaskDefinition = taskDef,
                    Image = ContainerImage.FromEcrRepository(repo, imageTag.ValueAsString),
                });
    
            // rest of stack...
        }
    }
    

    这允许您创建两个堆栈,非常简单地共享资源:

    var app = new App(new AppProps());
    
    var pipelineStack = new PipelineStack(app, "ExamplePipeline", new PipelineStackProps
    {
        // some props...
    });
    
    new ApiStack(app, apiStackName, new ApiStackProps
    {
        Repository = pipelineStack.EcrRepository,
    });
    

    这导致我创建了一系列堆栈,如下图所示,最顶层的堆栈需要来自下方的资源:

    出于上述原因,根据个人经验,我建议远离过多的堆栈间依赖项。在可能的情况下,将“共享”或引用的资源移动到您可以扩展的基本堆栈中(.NET's Lazy<T> 使得仅在访问时创建资源变得容易)。使用这种共享基础方法,堆栈的数量可能会减少,并允许更轻松的长期支持和更新:

    不幸的是,我没有关于第二种方法的良好公开示例,但是,上面的代码 sn-ps 来自我的 ECS CDK example repo,它在堆栈之间共享很多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-18
      • 1970-01-01
      • 1970-01-01
      • 2020-12-19
      • 2020-10-29
      • 2018-09-22
      • 2021-08-25
      • 2022-07-29
      相关资源
      最近更新 更多