

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 CloudFormation 管理安全群組
<a name="quickref-ec2-sg"></a>

下列程式碼片段示範如何使用 CloudFormation 管理安全群組和 Amazon EC2 執行個體，以控制對 AWS 資源的存取。

**Topics**
+ [將 Amazon EC2 執行個體與安全群組建立關聯](#quickref-ec2-instances-associate-security-group)
+ [使用傳入規則建立安全群組](#quickref-ec2-instances-ingress)
+ [使用安全群組傳入規則建立 Elastic Load Balancer](#scenario-ec2-security-group-elbingress)

## 將 Amazon EC2 執行個體與安全群組建立關聯
<a name="quickref-ec2-instances-associate-security-group"></a>

下列範例程式碼片段示範了如何使用 CloudFormation，將 Amazon EC2 執行個體與預設 Amazon VPC 安全群組建立關聯。

**Topics**
+ [將 Amazon EC2 執行個體與預設 VPC 安全群組建立關聯](#using-cfn-getatt-default-values)
+ [建立具有附接磁碟區和安全群組的 Amazon EC2 執行個體](#scenario-ec2-volumeattachment)

### 將 Amazon EC2 執行個體與預設 VPC 安全群組建立關聯
<a name="using-cfn-getatt-default-values"></a>

下列程式碼片段會建立 Amazon VPC、VPC 內的子網路以及 Amazon EC2 執行個體。VPC 使用 [AWS::EC2::VPC](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-vpc.html) 資源建立。VPC 的 IP 地址範圍在較大的範本中定義，並且 `MyVPCCIDRRange` 參數會參考該範圍。

子網路在 VPC 內使用 [AWS::EC2:: Subnet](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-subnet.html) 資源。子網路與 VPC 關聯，以 `MyVPC` 做為參考。

EC2 執行個體在 VPC 和子網路內使用 [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 資源啟動。此資源會指定用於啟動執行個體的 Amazon Machine Image (AMI)、執行執行個體所在的子網路，以及要與執行個體建立關聯的安全群組。`ImageId` 會使用 Systems Manager 參數動態擷取最新的 Amazon Linux 2 AMI。

安全群組 ID 使用 `Fn::GetAtt` 函數取得，該函數會從 `MyVPC` 資源擷取預設安全群組。

執行個體會放置在程式碼片段定義的 `MySubnet` 資源內。

當您使用 CloudFormation 建立 VPC 時， AWS 會自動在 VPC 內建立預設資源，包括預設安全群組。但是，若您在 CloudFormation 範本內定義 VPC，在建立範本時，可能無法存取這些預設資源的 ID。若要存取和使用範本中指定的預設資源，您可以使用內部函數，例如 `Fn::GetAtt`。此函數可讓您使用 CloudFormation 自動建立的預設資源。

#### JSON
<a name="quickref-ec2-example-15.json"></a>

```
"MyVPC": {
    "Type": "AWS::EC2::VPC",
    "Properties": {
        "CidrBlock": {
            "Ref": "MyVPCCIDRRange"
        },
        "EnableDnsSupport": false,
        "EnableDnsHostnames": false,
        "InstanceTenancy": "default"
    }
},
"MySubnet": {
    "Type": "AWS::EC2::Subnet",
    "Properties": {
        "CidrBlock": {
            "Ref": "MyVPCCIDRRange"
        },
        "VpcId": {
            "Ref": "MyVPC"
        }
    }
},
"MyInstance": {
    "Type": "AWS::EC2::Instance",
    "Properties": {
        "ImageId": "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
        "SecurityGroupIds": [
            {
                "Fn::GetAtt": [
                    "MyVPC",
                    "DefaultSecurityGroup"
                ]
            }
        ],
        "SubnetId": {
            "Ref": "MySubnet"
        }
    }
}
```

#### YAML
<a name="quickref-ec2-example-15.yaml"></a>

```
MyVPC:
  Type: AWS::EC2::VPC
  Properties:
    CidrBlock:
      Ref: MyVPCCIDRRange
    EnableDnsSupport: false
    EnableDnsHostnames: false
    InstanceTenancy: default
MySubnet:
  Type: AWS::EC2::Subnet
  Properties:
    CidrBlock:
      Ref: MyVPCCIDRRange
    VpcId:
      Ref: MyVPC
MyInstance:
  Type: AWS::EC2::Instance
  Properties:
    ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
    SecurityGroupIds:
      - Fn::GetAtt:
          - MyVPC
          - DefaultSecurityGroup
    SubnetId:
      Ref: MySubnet
```

### 建立具有附接磁碟區和安全群組的 Amazon EC2 執行個體
<a name="scenario-ec2-volumeattachment"></a>

下列程式碼片段會使用 [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 資源來建立 Amazon EC2 執行個體，該資源從指定的 AMI 啟動。執行個體與安全群組關聯，允許使用 [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源，在連接埠 22 上從指定的 IP 地址傳入 SSH 流量。它會使用 [AWS::EC2::Volume](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-volume.html) 資源來建立 100 GB 的 Amazon EBS 磁碟區。磁碟區建立在與執行個體相同的可用區域 (如 `GetAtt` 函數所指定)，並掛接至 `/dev/sdh` 裝置上的執行個體。

如需有關建立 Amazon EBS 磁碟區的詳細資訊，請參閱[建立 Amazon EBS 磁碟區](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-creating-volume.html)。

#### JSON
<a name="quickref-ec2-example-14.json"></a>

```
 1. "Ec2Instance": {
 2.     "Type": "AWS::EC2::Instance",
 3.     "Properties": {
 4.         "SecurityGroups": [
 5.             {
 6.                 "Ref": "InstanceSecurityGroup"
 7.             }
 8.         ],
 9.         "ImageId": "ami-1234567890abcdef0"
10.     }
11. },
12. "InstanceSecurityGroup": {
13.     "Type": "AWS::EC2::SecurityGroup",
14.     "Properties": {
15.         "GroupDescription": "Enable SSH access via port 22",
16.         "SecurityGroupIngress": [
17.             {
18.                 "IpProtocol": "tcp",
19.                 "FromPort": "22",
20.                 "ToPort": "22",
21.                 "CidrIp": "192.0.2.0/24"
22.             }
23.         ]
24.     }
25. },
26. "NewVolume": {
27.     "Type": "AWS::EC2::Volume",
28.     "Properties": {
29.         "Size": "100",
30.         "AvailabilityZone": {
31.             "Fn::GetAtt": [
32.                 "Ec2Instance",
33.                 "AvailabilityZone"
34.             ]
35.         }
36.     }
37. },
38. "MountPoint": {
39.     "Type": "AWS::EC2::VolumeAttachment",
40.     "Properties": {
41.         "InstanceId": {
42.             "Ref": "Ec2Instance"
43.         },
44.         "VolumeId": {
45.             "Ref": "NewVolume"
46.         },
47.         "Device": "/dev/sdh"
48.     }
49. }
```

#### YAML
<a name="quickref-ec2-example-14.yaml"></a>

```
 1. Ec2Instance:
 2.   Type: AWS::EC2::Instance
 3.   Properties:
 4.     SecurityGroups:
 5.       - !Ref InstanceSecurityGroup
 6.     ImageId: ami-1234567890abcdef0
 7. InstanceSecurityGroup:
 8.   Type: AWS::EC2::SecurityGroup
 9.   Properties:
10.     GroupDescription: Enable SSH access via port 22
11.     SecurityGroupIngress:
12.       - IpProtocol: tcp
13.         FromPort: 22
14.         ToPort: 22
15.         CidrIp: 192.0.2.0/24
16. NewVolume:
17.   Type: AWS::EC2::Volume
18.   Properties:
19.     Size: 100
20.     AvailabilityZone: !GetAtt [Ec2Instance, AvailabilityZone]
21. MountPoint:
22.   Type: AWS::EC2::VolumeAttachment
23.   Properties:
24.     InstanceId: !Ref Ec2Instance
25.     VolumeId: !Ref NewVolume
26.     Device: /dev/sdh
```

## 使用傳入規則建立安全群組
<a name="quickref-ec2-instances-ingress"></a>

下列範例程式碼片段示範了如何透過使用 CloudFormation 的特定傳入規則來設定安全群組。

**Topics**
+ [使用傳入規則建立安全群組以進行 SSH 和 HTTP 存取](#scenario-ec2-security-group-rule)
+ [使用傳入規則建立安全群組，以從指定的 CIDR 範圍進行 HTTP 和 SSH 存取](#scenario-ec2-security-group-two-ports)
+ [使用傳入規則建立相互參照的安全群組](#scenario-ec2-security-group-ingress)

### 使用傳入規則建立安全群組以進行 SSH 和 HTTP 存取
<a name="scenario-ec2-security-group-rule"></a>

下列程式碼片段描述了使用 [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源的兩個安全群組傳入規則。第一個輸入規則允許 SSH （連接埠 22) 從名為 的現有安全群組進行存取`MyAdminSecurityGroup`，該安全群組由帳號為 AWS 的帳戶所擁有`1111-2222-3333`。第二個傳入規則允許從稱為 `MySecurityGroupCreatedInCFN` 的不同安全群組存取 HTTP (通訊埠 80)，該安全群組在相同範本中建立。`Ref` 函數用於參考在相同範本中建立的安全群組的邏輯名稱。

在第一個傳入規則中，您必須為 `SourceSecurityGroupName` 和 `SourceSecurityGroupOwnerId` 屬性新增值。在第二個傳入規則中，`MySecurityGroupCreatedInCFNTemplate` 會參考在相同範本中建立的不同安全群組。確認邏輯名稱 `MySecurityGroupCreatedInCFNTemplate` 與您在較大範本中指定的安全群組資源的實際邏輯名稱相符。

如需安全群組的詳細資訊，請參閱《*Amazon EC2 使用者指南*》中的 [Amazon EC2 執行個體的 Amazon EC2 安全群組](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)。

#### JSON
<a name="quickref-ec2-example-10.json"></a>

```
 1. "SecurityGroup": {
 2.     "Type": "AWS::EC2::SecurityGroup",
 3.     "Properties": {
 4.         "GroupDescription": "Allow connections from specified source security group",
 5.         "SecurityGroupIngress": [
 6.             {
 7.                 "IpProtocol": "tcp",
 8.                 "FromPort": "22",
 9.                 "ToPort": "22",
10.                 "SourceSecurityGroupName": "MyAdminSecurityGroup",
11.                 "SourceSecurityGroupOwnerId": "1111-2222-3333"
12.             },
13.             {
14.                 "IpProtocol": "tcp",
15.                 "FromPort": "80",
16.                 "ToPort": "80",
17.                 "SourceSecurityGroupName": {
18.                     "Ref": "MySecurityGroupCreatedInCFNTemplate"
19.                 }
20.             }
21.         ]
22.     }
23. }
```

#### YAML
<a name="quickref-ec2-example-10.yaml"></a>

```
 1. SecurityGroup:
 2.   Type: AWS::EC2::SecurityGroup
 3.   Properties:
 4.     GroupDescription: Allow connections from specified source security group
 5.     SecurityGroupIngress:
 6.       - IpProtocol: tcp
 7.         FromPort: '22'
 8.         ToPort: '22'
 9.         SourceSecurityGroupName: MyAdminSecurityGroup
10.         SourceSecurityGroupOwnerId: '1111-2222-3333'
11.       - IpProtocol: tcp
12.         FromPort: '80'
13.         ToPort: '80'
14.         SourceSecurityGroupName:
15.           Ref: MySecurityGroupCreatedInCFNTemplate
```

### 使用傳入規則建立安全群組，以從指定的 CIDR 範圍進行 HTTP 和 SSH 存取
<a name="scenario-ec2-security-group-two-ports"></a>

下列程式碼片段會針對具有兩個傳入規則的 Amazon EC2 執行個體建立安全群組。傳入規則允許從指定 CIDR 範圍的指定連接埠上傳入 TCP 流量。[AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源用於指定規則。您必須針對每項規則指定協定。針對 TCP，您必須指定連接埠或連接埠範圍。如果您未指定來源安全群組或 CIDR 範圍，堆疊會成功啟動，但不會將規則套用至安全群組。

如需安全群組的詳細資訊，請參閱《*Amazon EC2 使用者指南*》中的 [Amazon EC2 執行個體的 Amazon EC2 安全群組](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)。

#### JSON
<a name="quickref-ec2-example-9.json"></a>

```
 1. "ServerSecurityGroup": {
 2.   "Type": "AWS::EC2::SecurityGroup",
 3.   "Properties": {
 4.     "GroupDescription": "Allow connections from specified CIDR ranges",
 5.     "SecurityGroupIngress": [
 6.       {
 7.         "IpProtocol": "tcp",
 8.         "FromPort": "80",
 9.         "ToPort": "80",
10.         "CidrIp": "192.0.2.0/24"
11.       },
12.       {
13.         "IpProtocol": "tcp",
14.         "FromPort": "22",
15.         "ToPort": "22",
16.         "CidrIp": "192.0.2.0/24"
17.       }
18.     ]
19.   }
20. }
```

#### YAML
<a name="quickref-ec2-example-9.yaml"></a>

```
 1. ServerSecurityGroup:
 2.   Type: AWS::EC2::SecurityGroup
 3.   Properties:
 4.     GroupDescription: Allow connections from specified CIDR ranges
 5.     SecurityGroupIngress:
 6.       - IpProtocol: tcp
 7.         FromPort: 80
 8.         ToPort: 80
 9.         CidrIp: 192.0.2.0/24
10.       - IpProtocol: tcp
11.         FromPort: 22
12.         ToPort: 22
13.         CidrIp: 192.0.2.0/24
```

### 使用傳入規則建立相互參照的安全群組
<a name="scenario-ec2-security-group-ingress"></a>

下列程式碼片段使用 [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源來建立兩個 Amazon EC2 安全群組 (`SGroup1` 和 `SGroup2`)。允許兩個安全群組之間進行通訊的傳入規則使用 [AWS::EC2::SecurityGroupIngress](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroupingress.html) 資源建立。`SGroup1Ingress` 會建立 `SGroup1` 的傳入規則，以允許來源安全群組 `SGroup2` 連接埠 80 上的傳入 TCP 流量。`SGroup2Ingress` 會建立 `SGroup2` 的傳入規則，以允許來源安全群組 `SGroup1` 連接埠 80 上的傳入 TCP 流量。

#### JSON
<a name="quickref-ec2-example-12.json"></a>

```
 1. "SGroup1": {
 2.     "Type": "AWS::EC2::SecurityGroup",
 3.     "Properties": {
 4.         "GroupDescription": "EC2 instance access"
 5.     }
 6. },
 7. "SGroup2": {
 8.     "Type": "AWS::EC2::SecurityGroup",
 9.     "Properties": {
10.         "GroupDescription": "EC2 instance access"
11.     }
12. },
13. "SGroup1Ingress": {
14.     "Type": "AWS::EC2::SecurityGroupIngress",
15.     "Properties": {
16.         "GroupName": {
17.             "Ref": "SGroup1"
18.         },
19.         "IpProtocol": "tcp",
20.         "ToPort": "80",
21.         "FromPort": "80",
22.         "SourceSecurityGroupName": {
23.             "Ref": "SGroup2"
24.         }
25.     }
26. },
27. "SGroup2Ingress": {
28.     "Type": "AWS::EC2::SecurityGroupIngress",
29.     "Properties": {
30.         "GroupName": {
31.             "Ref": "SGroup2"
32.         },
33.         "IpProtocol": "tcp",
34.         "ToPort": "80",
35.         "FromPort": "80",
36.         "SourceSecurityGroupName": {
37.             "Ref": "SGroup1"
38.         }
39.     }
40. }
```

#### YAML
<a name="quickref-ec2-example-12.yaml"></a>

```
 1. SGroup1:
 2.   Type: AWS::EC2::SecurityGroup
 3.   Properties:
 4.     GroupDescription: EC2 Instance access
 5. SGroup2:
 6.   Type: AWS::EC2::SecurityGroup
 7.   Properties:
 8.     GroupDescription: EC2 Instance access
 9. SGroup1Ingress:
10.   Type: AWS::EC2::SecurityGroupIngress
11.   Properties:
12.     GroupName: !Ref SGroup1
13.     IpProtocol: tcp
14.     ToPort: 80
15.     FromPort: 80
16.     SourceSecurityGroupName: !Ref SGroup2
17. SGroup2Ingress:
18.   Type: AWS::EC2::SecurityGroupIngress
19.   Properties:
20.     GroupName: !Ref SGroup2
21.     IpProtocol: tcp
22.     ToPort: 80
23.     FromPort: 80
24.     SourceSecurityGroupName: !Ref SGroup1
```

## 使用安全群組傳入規則建立 Elastic Load Balancer
<a name="scenario-ec2-security-group-elbingress"></a>

下列範本會在指定的可用區域建立 [AWS::ElasticLoadBalancing::LoadBalancer](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancing-loadbalancer.html) 資源。[AWS::ElasticLoadBalancing::LoadBalancer](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancing-loadbalancer.html) 資源設定為在連接埠 80 上接聽 HTTP 流量，請求也會引導至連接埠 80 上的執行個體。Elastic Load Balancer 負責對執行個體之間的傳入 HTTP 流量進行負載平衡。

 此外，此範本會產生與負載平衡器關聯的 [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源。此安全群組使用單一傳入規則建立，描述為 `ELB ingress group`，這會允許連接埠 80 上的傳入 TCP 流量。此傳入規則的來源 `Fn::GetAtt` 函數定義，以從負載平衡器資源擷取屬性。`SourceSecurityGroupOwnerId` 使用 `Fn::GetAtt` 來取得負載平衡器來源安全群組的 `OwnerAlias`。`SourceSecurityGroupName` 使用 `Fn::Getatt` 來取得 ELB 來源安全群組的 `GroupName`。

此設定可確保 ELB 與執行個體之間進行安全通訊。

如需負載平衡的詳細資訊，請參閱 [Elastic Load Balancing 使用者指南](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/)。

### JSON
<a name="quickref-ec2-example-11.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "MyELB": {
            "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
            "Properties": {
                "AvailabilityZones": [
                    "aa-example-1a"
                ],
                "Listeners": [
                    {
                        "LoadBalancerPort": "80",
                        "InstancePort": "80",
                        "Protocol": "HTTP"
                    }
                ]
            }
        },
        "MyELBIngressGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "ELB ingress group",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 80,
                        "ToPort": 80,
                        "SourceSecurityGroupOwnerId": {
                            "Fn::GetAtt": [
                                "MyELB",
                                "SourceSecurityGroup.OwnerAlias"
                            ]
                        },
                        "SourceSecurityGroupName": {
                            "Fn::GetAtt": [
                                "MyELB",
                                "SourceSecurityGroup.GroupName"
                            ]
                        }
                    }
                ]
            }
        }
    }
}
```

### YAML
<a name="quickref-ec2-example-11.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyELB:
    Type: AWS::ElasticLoadBalancing::LoadBalancer
    Properties:
      AvailabilityZones:
        - aa-example-1a
      Listeners:
        - LoadBalancerPort: '80'
          InstancePort: '80'
          Protocol: HTTP
  MyELBIngressGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: ELB ingress group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          SourceSecurityGroupOwnerId:
            Fn::GetAtt:
              - MyELB
              - SourceSecurityGroup.OwnerAlias
          SourceSecurityGroupName:
            Fn::GetAtt:
              - MyELB
              - SourceSecurityGroup.GroupName
```