繁体   English   中英

CloudFormation - 根据 vpc 标签值将安全组动态分配给 vpc

[英]CloudFormation - Assign a security group to a vpc dynamically based on a vpc tag value

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

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

显然,如果我没有在 VpcId 字段中指定 VPC ID,它会创建安全组,但将其附加到该账户的默认 VPC。 我也无法手动指定 VPC,因为它将在多个账户中运行。 通过运行某种 function 来提取“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 的人那里得到一些意见,那会对我有很大帮助。

动态获取“VpcId”。

您必须为此使用自定义资源 您必须将其创建为lambda function ,它将采用您想要的任何输入 arguments,并使用 AWS SDK 查询或修改堆栈中的 VPC/安全组。

感谢 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 function 中的过滤器获得返回值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM