【问题标题】:CloudFormation - Assign a security group to a vpc dynamically based on a vpc tag valueCloudFormation - 根据 vpc 标签值动态地将安全组分配给 vpc
【发布时间】:2021-09-28 23:52:50
【问题描述】:

我有一个组织帐户,其下有多个客户帐户。每个托管账户中都有多个 VPC。每个托管账户中的一个 VPC 将有一个标签“ServiceName”:“True”,而该账户中的其他 VPC 将有一个“ServiceName”:“False”标签。

我正在尝试创建一个堆栈集,其堆栈专用于创建一个附加了入口规则的安全组,我需要将该安全组的“VpcId”属性动态分配为 VPC 的“VpcId”该帐户中的 "ServiceName":"True" 标记。

显然,如果我没有在 VpcId 字段中指定 VPC ID,它会创建安全组,但会将其附加到该帐户的默认 VPC。我也无法手动指定 VPC,因为它将在多个账户中运行。通过运行某种函数来提取“VpcId”,我只能选择搜索和分配 VPC。

堆栈本身运行良好,因为我在测试环境中运行它并指定了 VPC ID。因此,只需动态获取“VpcId”即可。

最后,我想做一些类似这样的事情:

{
"Parameters": {
    "MyValidVPCID": {
        "Description": "My Valid VPC ID where ServiceName tag equals true. Do some Lambda Kung Fu to get the VPC ID using something that would let me parse the equivalent of aws ec2 describe-vpcs command.",
        "Type": "String"
    }
},
"Resources": {
    "SG": {
        "Type": "AWS::EC2::SecurityGroup",
        "Properties": {
            "GroupDescription": "Security Group Desc.",
            "Tags": [
                {
                    "Key": "Key1",
                    "Value": "ABC"
                },
                {
                    "Key": "Key2",
                    "Value": "DEF"
                }
            ],
    "VpcId" : { "Ref" : "MyValidVPCID" }
        }
    },
    "SGIngressRule01":
    {
        "Type": "AWS::EC2::SecurityGroupIngress",
        "DependsOn": "SG",
        "Properties": {
            "GroupId" : { "Fn::GetAtt": [ "SG", "GroupId" ] },
            "Description": "Rule 1 description",
            "IpProtocol": "tcp",
            "FromPort": 123,
            "ToPort": 456,
            "CidrIp": "0.0.0.0/0"
        }
    }
}

我真的不知道这是否是一种可行的方法,或者根据标签恢复 VpcId 所需的额外步骤是什么。这就是为什么如果我能从曾经使用 CloudFormation 的人那里获得一些意见,那将对我有很大帮助。

【问题讨论】:

  • 仍在努力,从星期四开始我就一直不在办公室。你绝对把我引向了正确的方向!到目前为止,我能够生成一个 python Lambda 函数来根据所需的过滤器返回我正在寻找的 VPC ID。正如我们所说,我正在努力将其植入我的 CloudFormation 模板中。我们会看看它是如何运行的,一旦它运行起来就会报告!

标签: amazon-web-services amazon-cloudformation


【解决方案1】:

动态获取“VpcId”。

您必须为此使用custom resource。您必须将其创建为 lambda 函数,该函数将接受您想要的任何输入参数,并使用 AWS SDK 查询或修改堆栈中的 VPC/安全组。

【讨论】:

    【解决方案2】:

    感谢 Marcin 为我指明了自定义资源的正确方向。对于那些想知道使它工作的基本代码是什么样子的人,它看起来像这样:

    Resources:
    
      FunctionNameLambdaFunctionRole:
        Type: "AWS::IAM::Role"
        Properties:
          RoleName: FunctionNameLambdaFunctionRole
          Path: "/"
          AssumeRolePolicyDocument:
              Version: "2012-10-17"
              Statement:
                  - Effect: Allow
                    Principal:
                      Service: lambda.amazonaws.com
                    Action: sts:AssumeRole
      
      FunctionNameLambdaFunctionRolePolicy:
        Type: "AWS::IAM::Policy"
        Properties:
            PolicyName: admin3cx
            PolicyDocument:
                Version: "2012-10-17"
                Statement:
                  - Effect: "Allow"
                    Action: "*"
                    Resource: "*"
            Roles:
              - Ref: FunctionNameLambdaFunctionRole
    
      FunctionNameLambdaFunctionCode:
        Type: "AWS::Lambda::Function"
        DeletionPolicy: Delete
        DependsOn:
          - FunctionNameLambdaFunctionRole
        Properties:
            FunctionName: FunctionNameLambdaFunctionCode
            Role: !GetAtt FunctionNameLambdaFunctionRole.Arn
            Runtime: python3.7
            Handler: index.handler
            MemorySize: 128
            Timeout: 30
            Code:
              ZipFile: |
                import boto3
                import cfnresponse
                ec2 = boto3.resource('ec2')
                client = boto3.client('ec2')
                def handler(event, context):
                  responseData = {}
                  filters =[{'Name':'tag:ServiceName', 'Values':['True']}]
                  vpcs = list(ec2.vpcs.filter(Filters=filters))
                  for vpc in vpcs:
                    responseVPC = vpc.id
                  responseData['ServiceName'] = responseVPC
                  cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
    
      FunctionNameLambdaFunctionInvocationCode:
        Type: "Custom::FunctionNameLambdaFunctionInvocationCode"
        Properties:
          ServiceToken: !GetAtt FunctionNameLambdaFunctionCode.Arn
    
      SGFunctionName:
        Type: "AWS::EC2::SecurityGroup"
        Properties:
          GroupDescription: Description
          VpcId: !GetAtt FunctionNameLambdaFunctionInvocationCode.ServiceName
          
       ...
    

    一些内容已被编辑,我切换到 YAML。代码显然会被细化。重点是确保我能够根据 CloudFormation 堆栈内的 Lambda 函数中的过滤器获得返回值。

    【讨论】:

      猜你喜欢
      • 2021-01-14
      • 2016-05-12
      • 2021-06-28
      • 2015-08-01
      • 2020-06-28
      • 1970-01-01
      • 2020-10-21
      • 2014-04-17
      • 1970-01-01
      相关资源
      最近更新 更多