【问题标题】:How to Import Security group from another stack using #AWS-CDK?如何使用 #AWS-CDK 从另一个堆栈导入安全组?
【发布时间】:2019-03-26 03:36:21
【问题描述】:

我想知道如何导入在另一个堆栈中定义的安全组,然后在当前堆栈中使用。

到目前为止,我已经尝试过了..

class relayStack extends cdk.Stack {
    public sg_relay: ec2.SecurityGroupRefProps

    constructor(parent: cdk.App, name: string, props: VPCProps) {
        super(parent, name, props);

        //#IMPORT VPC PROPS
        const vpc = ec2.VpcNetwork.import(this, 'VPC-Hottest100', props.infra.vpc);
        //#AUTOSCALING GROUP
        const asg_relayServer = new ec2.AutoScalingGroup(this, 'ASG_Relay', {
            vpc,
            instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.T2, ec2.InstanceSize.Small),
            minSize: 1,
            maxSize: 3,
            desiredCapacity: 1,
            machineImage: new ec2.GenericLinuxImage({
                "ap-southeast-2": "ami-dc361ebf",
            }),
            keyName: 'icecast-poc',
            allowAllOutbound: false,
            vpcPlacement: {
                usePublicSubnets: false
            }
        });

        //#SECURITY Group
        const sg_relay = new ec2.SecurityGroup(this, 'SG_RELAY', {
            vpc,
            description: "Relay stack security group",
            groupName: 'relay-sg'
        })


        this.sg_relay = sg_relay
    }
}

然后我想从另一个堆栈访问导出的安全组 sg_relay

我已尝试关注

//#SECURITY GROUP
const sg_nginx = new ec2.SecurityGroup(this, "SG_NGINX", {
    vpc,
    description: "NGINX stack security group",
    groupName: 'nginx-sg'
})

const sg_relayImp = new ec2.SecurityGroupRef(this, "SG_RELAY_IMP", {
    securityGroupId: new ec2.SecurityGroupId('SG_RELAY')
})

然后如下使用

sg_nginx.addIngressRule(sg_relayImp, wowzaPort, 'asg_RelyToNgn_8000')

显然它不适合我。

我找不到堆栈之间安全组的任何导入函数,就像 vpc 有一个。

有人可以帮我解决这种情况吗?

【问题讨论】:

    标签: aws-cdk


    【解决方案1】:

    您可以在最初定义安全组的堆栈中使用SecurityGroup.export,这将创建一个带有生成的导出名称的堆栈Output,并将您需要传递给SecurityGroupRef.import的数据返回给获取对另一个堆栈中安全组的引用。

    您需要确保首先部署定义安全组的堆栈,否则其他堆栈将无法从该堆栈的输出导入。

    【讨论】:

    • 有没有通用的解决方案?我的意思是,如果输出是其他东西,比如 DynamoDB 表的 ARN,该怎么办?
    • 导出/导入已在最新的 CDK 版本中被删除。它不再起作用了。
    • 虽然这不再是一个选项,但对于不使用 CDK 的人来说,它仍然是一个很好的答案,因为这几乎就是您使用常规 CloudFormation 要做的事情。 CDK 允许您避免以这种方式进行导出/导入,从而使生活变得轻松。
    【解决方案2】:

    假设有问题的堆栈都在您的 CDK 应用程序下,您可以使用堆栈输出来共享资源。

    这里的文档:https://docs.aws.amazon.com/cdk/api/latest/docs/core-readme.html#stack-outputs

    我发现this blog post 作为一个有用的例子(不是我写的)

    应该适用于您可能希望在堆栈之间引用的任何资源。

    编辑:这是我目前正在使用的。

    // I have a resource which is a cloudfront dist id in StackA
    new cdk.CfnOutput(this, 'cloudfront-dist-id-output', {
          description: 'cloudfront-dist-id-output',
          exportName: 'cloudfront-dist-id-output',
          value: cloudFrontDistribution.distributionId
        });
    
    // Stack B needs the DistributionId (it's dynamic), so I pass it in as a parameter.
    new StackB(app, 'StackB', Fn.importValue('cloudfront-dist-id-output'));
    

    唯一“已知”的东西是您正在输出的参数的名称。

    这实际上与您在其他答案中提供的内容相同,但 CDK 会为您写入 Fn.importValue

    警告:不适用于位于不同区域的堆栈中的资源。 CloudFormation 施加的限制也将发生在@Kane 的回答中。

    【讨论】:

    • 您能否通过示例更新答案以演示如何使用输出和导入?
    • @Kane 我已经更新了答案。请注意,CloudFormation 对 Fn.importValue 施加了限制。您不能引用部署在不同区域的堆栈中的内容。
    • @charlybones 所以它必须作为参数传递?我们不能直接在堆栈的构造函数中导入吗?它与上面的其他答案有何不同?由于另一个答案,我们不需要显式导出和导入
    • 这是一个非常有用的答案。我之前曾将一个堆栈的引用传递到另一个堆栈,但这导致每次我想更新第二个堆栈时都部署两者。使用这种堆栈导出方法,我可以将所需的 Arn 导入另一个堆栈,而不会产生巨大的依赖性。很棒的提示。
    【解决方案3】:

    您可以直接在应用中引用跨栈资源。

    下面是代码sn-p,

    export class InfraCdkStack extends cdk.Stack {
      // Create a readonly property to reference on an instance.
      readonly vpc: ec2.IVpc;
    
      constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
        super(scope, id, props);
    
        // The code that defines your stack goes here.
        // Assign your vpc to your previously created property.
        // Creates a vpc in two AZs.
        this.vpc = new ec2.Vpc(this, 'MyVPC');
      }
    }
    
    // Create an interface to hold the vpc information.
    interface ECSStackProps extends cdk.StackProps {
      vpc: ec2.IVpc;
    }
    
    // Have your class constructor accept the interface.
    export class ECSCdkStack extends cdk.Stack {
      constructor(scope: cdk.Construct, id: string, props: ECSStackProps) {
        super(scope, id, props);
    }
    
    const app = new cdk.App();
    const infraStack = new InfraCdkStack(app, 'InfraCdkStack');
    // Pass the infraStack.vpc property to the ECSCdkStack class.
    const gameECSStack = new ECSCdkStack(app, 'ECSCdkStack', {
        vpc: infraStack.vpc
    });
    

    an example in official doc to demonstrate how sharing s3 bucket

    【讨论】:

    • 谢谢。我想知道是否有跨回购价值导入的支持或示例?
    • 查看静态方法fromBucketXxx。注意,导入的资源大多是只读的。
    【解决方案4】:

    在堆栈 A 中创建一个像这样的示例安全组。

    const sampleSecurityGroup = new ec2.SecurityGroup(this, 'security-group', { vpc: vpc, allowAllOutbound: true, description: 'Security Group Sample', securityGroupName: "SAMPLE-SG" });
    

    在堆栈 A 中使用以下导出 SG。

    const myoutput = new cdk.CfnOutput(this, 'Security-group-id-output', { description: 'Security group in Stack A', exportName: 'security-id-output', value: sampleSecurityGroup.securityGroupId });
    

    在 UI 中检查 Cloud Formation 服务,您应该会看到名为“security-id-output”的导出。

    在堆栈 B 中使用

    导入值
    cdk.Fn.importValue("security-id-output");
    

    【讨论】:

    • 这对我不起作用 :(。两个堆栈是否必须在同一个 cdk.App 下?或者两个堆栈在同一个帐户和区域中就足够了吗?
    猜你喜欢
    • 1970-01-01
    • 2022-01-27
    • 2020-08-12
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 2020-04-03
    • 2013-07-23
    相关资源
    最近更新 更多