AWS CloudFormation:VPC 默认安全组

AWS CloudFormation:VPC 默认安全组

我有一个 cfn 堆栈,它(除其他外)创建了一个 VPC、几个安全组和一些 EC2 实例。将堆栈内创建的安全组分配给同样由堆栈创建的实例很简单。但是,我对默认 VPC SG 感兴趣。

当创建 VPC 时(无论是通过 GUI 手动创建,还是通过 cloudformation 或任何其他方式),AWS 都会为该组中的任何实例创建一个具有“允许所有”规则的默认安全组。

我试图将此默认安全组以及其他几个 SG 分配给堆栈创建的实例。事实证明,这比我预想的要困难得多。以下是一些显示我正在做的事情的代码片段:

"AllowSSHSecGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Allow SSH from anywhere",
        "VpcId":{
          "Ref":"DevVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":"0.0.0.0/0"
          }
        ]
      }
},
"Instance001" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : "ami-7eab224e",
        "InstanceType" : "m1.large",
        "AvailabilityZone" : "us-west-2a",
        "PrivateIpAddress" : "10.22.0.110",
        "SecurityGroupIds" : [ {"Ref" : "AllowSSHSecGroup"} ],
        "SubnetId" : { "Ref" : "PublicSubnet" },
        "KeyName" : "erik-key",
        "DisableApiTermination" : "false",
        "Tags" : [ { "Key": "Name", "Value": "Instance001"} ]
      }
}

在上面的代码片段中,我创建了一个“允许 ssh”安全组并将其分配给一个实例。如上所述,我的堆栈还创建了一个 VPC(此实例在其中启动),而这又会创建一个默认安全组。不幸的是,由于此组是由 AWS 自动创建的,因此其组 ID 对堆栈不可用,因此无法通过 ID 引用。我最初认为该SecurityGroups属性是一个选项,因为这将允许我通过其名称引用默认 SG。default但这不起作用,因为该SecurityGroups属性仅适用于 EC2 安全组,而不适用于 VPC 安全组。

所以我被困住了。我就此问题向 AWS 支持部门提交了案例,但到目前为止,他们还没有提供帮助。关于如何实现此目标,您有什么想法吗?

答案1

可以使用以下方法引用默认安全组:

{ "Fn::GetAtt" : ["VPC", "DefaultSecurityGroup"] }

其中“VPC”是您的 VPC 资源名称。

使用AWS::EC2::SecurityGroupIngressAWS::EC2::SecurityGroupEgress,您可以增强此默认安全组的权限。

我想这就是你想要的:

"VPCDefaultSecurityGroupIngress": {
  "Type" : "AWS::EC2::SecurityGroupIngress",
  "Properties" : {
    "GroupId": { "Fn::GetAtt" : ["VPC", "DefaultSecurityGroup"] },
    "IpProtocol":"tcp",
    "FromPort":"22",
    "ToPort":"22",
    "CidrIp":"0.0.0.0/0"
  }
},

正如@artbristol 和@gabriel 所提到的,这允许将 Ingress/Egress 规则添加到单堆栈部署中 VPC 的默认安全组。

我非常确定,自引用问题仍然会影响任何尝试更改 VPC 默认安全组上任何其他属性的行为。一个很好的例子就是添加标签或描述。如果您希望更改这些内容,则必须处理周围的无关安全组。

答案2

事实证明,AWS 支持回复并通知我,他们认识到这是 CloudFormation 中的一个功能缺陷,并且已将其作为功能请求提交给开发团队。

因此,在实现此功能之前,解决方法是创建您自己的“默认”安全组,该安全组复制与“真实”默认 SG 相同的行为。不幸的是,由于此设置的自引用方面,仍然无法在单个堆栈部署中执行此操作。另一种方法是部署堆栈一次,而不将默认安全组分配给您的实例。然后,一旦创建了堆栈(并且您有机会看到默认的安全组 ID 是什么),您就可以将该 SG ID 添加到您的实例中。

答案3

截至撰写 2020 年 12 月更新/扩展时,

稍微扩展一下回答

对于一些参考资料,获取默认安全组,您现在可以使用此处引用的获取属性AWS Cloudformation VPC 文档

我个人使用 yaml,因此如果这可以帮助其他想知道如何在 yaml 中引用 VPC 的默认安全组,方法如下:

!GetAtt VPC.DefaultSecurityGroup

还显示了取自此处的 yaml 格式的示例回答从上下文来看:

myELBIngressGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: ELB ingress group
    SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        GroupId: !GetAtt VPC.DefaultSecurityGroup
        CidrIp: "0.0.0.0/0"

相关内容