

# 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` パラメータによって参照されます。

サブネットは [AWS::EC2:: Subnet](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-subnet.html) リソースを使用します。サブネットは、`MyVPC` として参照される VPC に関連付けられています。

EC2 インスタンスは、[AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) リソースを使用して VPC とサブネット内で起動されます。このリソースは、インスタンスの起動に使用する Amazon マシンイメージ (AMI)、インスタンスが実行されるサブネット、インスタンスに関連付けるセキュリティグループを指定します。`ImageId` は Systems Manager パラメータを使用して、最新の Amazon Linux 2 AMI を動的に取得します。

セキュリティグループ ID は、`MyVPC` リソースからデフォルトのセキュリティグループを取得する `Fn::GetAtt` 関数を使用して取得されます。

インスタンスはスニペットで定義された `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>

次のスニペットは、指定した AMI から起動する [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) リソースを使用する Amazon EC2 インスタンスを作成します。インスタンスは、[AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) リソースを使用して、指定された IP アドレスからポート 22 で受信する 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>

このスニペットは、2 つのセキュリティグループ進入ルールが記述された [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) リソースを示します。最初の進入ルールは、アカウント番号 `1111-2222-3333` を持つ AWS アカウントが所有する、`MyAdminSecurityGroup` という名前の既存のセキュリティグループからの SSH (ポート 22) アクセスを許可します。2 番目の進入ルールは、同じテンプレートで作成された、`MySecurityGroupCreatedInCFN` という名前の別のセキュリティグループからの HTTP (ポート 80) アクセスを許可します。`Ref` 関数は、同じテンプレートで作成されたセキュリティグループの論理名を参照するために使用されます。

最初の進入ルールでは、`SourceSecurityGroupName` と `SourceSecurityGroupOwnerId` プロパティの両方に値を追加する必要があります。2 番目の進入ルールでは、`MySecurityGroupCreatedInCFNTemplate` は同じテンプレートで作成された別のセキュリティグループを参照します。論理名が、大きい方のテンプレートで指定するセキュリティグループリソースの実際の論理名 `MySecurityGroupCreatedInCFNTemplate` と一致することを確認してください。

セキュリティグループの詳細については、「[Amazon EC2 ユーザーガイド](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)」の「*Amazon EC2 インスタンス用の Amazon EC2 セキュリティグループ*」を参照してください。

#### 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>

次のスニペットは、2 つのインバウンドルールを持つ Amazon EC2 インスタンスのセキュリティグループを作成します。インバウンドルールは、指定された CIDR 範囲からの指定ポートへの受信 TCP トラフィックを許可します。[AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) リソースは、ルールの指定に使用されます。各ルールのプロトコルを指定する必要があります。TCP の場合は、ポートまたはポート範囲も指定する必要があります。ソースセキュリティグループまたは CIDR 範囲のいずれも指定しない場合、スタックは正常に起動しますが、ルールはセキュリティグループに適用されません。

セキュリティグループの詳細については、「[Amazon EC2 ユーザーガイド](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)」の「*Amazon EC2 インスタンス用の Amazon EC2 セキュリティグループ*」を参照してください。

#### 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) リソースを使用して、`SGroup1` と `SGroup2` の 2 つの Amazon EC2 セキュリティグループを作成します。2 つのセキュリティグループ間の通信を許可する進入ルールは、[AWS::EC2::SecurityGroupIngress](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroupingress.html) リソースを使用して作成されます。`SGroup1Ingress` は、送信元セキュリティグループ `SGroup2` からポート 80 で受信 TCP トラフィックを許可する `SGroup1` の進入ルールを確立します。`SGroup2Ingress` は、送信元セキュリティグループ `SGroup1` からのポート 80 への着信 TCP トラフィックを許可する `SGroup2` の進入ルールを確立します。

#### 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) リソースを生成します。このセキュリティグループは、ポート 80 での着信 TCP トラフィックを許可する、`ELB ingress group` という 1 つの進入ルールを使用して作成されます。この進入ルールのソースは、ロードバランサーリソースから属性を取得する `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
```