AWS CloudFormation を使用したセキュリティグループの管理 - AWS CloudFormation

AWS CloudFormation を使用したセキュリティグループの管理

以下のスニペットは、AWS CloudFormation を使用してセキュリティグループと Amazon EC2 インスタンスを管理し、AWS リソースへのアクセスを制御する方法を示しています。

Amazon EC2 インスタンスをセキュリティグループと関連付けるには

次のスニペットは、AWS CloudFormation を使用して Amazon EC2 インスタンスをデフォルトの Amazon VPC セキュリティグループに関連付ける方法を示します。

Amazon EC2 インスタンスをデフォルトの VPC セキュリティグループと関連付けるには

次のスニペットは、Amazon VPC、VPC 内のサブネット、Amazon EC2 インスタンスを作成します。VPC は AWS::EC2::VPC リソースを使用して作成されます。VPC の IP アドレス範囲は、大きい方のテンプレートで定義され、MyVPCCIDRRange パラメータによって参照されます。

サブネットは AWS::EC2:: Subnet リソースを使用します。サブネットは、MyVPC として参照される VPC に関連付けられています。

EC2 インスタンスは、AWS::EC2::Instance リソースを使用して VPC とサブネット内で起動されます。このリソースは、インスタンスの起動に使用する Amazon マシンイメージ (AMI)、インスタンスが実行されるサブネット、インスタンスに関連付けるセキュリティグループを指定します。Fn::FindInMap 関数は、テンプレートで定義された AWSRegionToAMI マッピングから値を取得し、AWS::EC2::Instance リソースの ImageId を決定するために使用されます。

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

インスタンスはスニペットで定義された MySubnet リソース内に配置されます。

AWS CloudFormation を使用して VPC を作成すると、AWS はデフォルトのセキュリティグループを含むデフォルトリソースを自動的に作成します。ただし、AWS CloudFormation テンプレート内で VPC を定義すると、テンプレートを作成するときにこれらのデフォルトリソースの ID にアクセスできない場合があります。テンプレートで指定されているデフォルトリソースにアクセスして使用するには、Fn::GetAtt などの組み込み関数を使用できます。この関数を使用すると、AWS CloudFormation によって自動的に作成されたデフォルトリソースを使用できます。

JSON

"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": { "Fn::FindInMap": [ "AWSRegionToAMI", { "Ref": "AWS::Region" }, "64" ] }, "SecurityGroupIds": [ { "Fn::GetAtt": [ "MyVPC", "DefaultSecurityGroup" ] } ], "SubnetId": { "Ref": "MySubnet" } } }

YAML

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: Fn::FindInMap: - AWSRegionToAMI - Ref: AWS::Region - "64" SecurityGroupIds: - Fn::GetAtt: - MyVPC - DefaultSecurityGroup SubnetId: Ref: MySubnet

ボリュームとセキュリティグループをアタッチした Amazon EC2 インスタンスを作成する

次のスニペットは、指定した AMI から起動する AWS::EC2::Instance リソースを使用する Amazon EC2 インスタンスを作成します。インスタンスは、AWS::EC2::SecurityGroup リソースを使用して、指定された IP アドレスからポート 22 で受信する SSH トラフィックを許可するセキュリティグループに関連付けられています。AWS::EC2::Volume リソースを使用して 100 GB の Amazon EBS ボリュームを作成します。ボリュームは、GetAtt 関数で指定されたインスタンスと同じアベイラビリティーゾーンに作成され、/dev/sdh デバイスのインスタンスにマウントされます。

Amazon EBS ボリュームの作成の詳細については、「Amazon EBS ボリュームの作成」を参照してください。

JSON

"Ec2Instance": { "Type": "AWS::EC2::Instance", "Properties": { "SecurityGroups": [ { "Ref": "InstanceSecurityGroup" } ], "ImageId": "ami-1234567890abcdef0" } }, "InstanceSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Enable SSH access via port 22", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "192.0.2.0/24" } ] } }, "NewVolume": { "Type": "AWS::EC2::Volume", "Properties": { "Size": "100", "AvailabilityZone": { "Fn::GetAtt": [ "Ec2Instance", "AvailabilityZone" ] } } }, "MountPoint": { "Type": "AWS::EC2::VolumeAttachment", "Properties": { "InstanceId": { "Ref": "Ec2Instance" }, "VolumeId": { "Ref": "NewVolume" }, "Device": "/dev/sdh" } }

YAML

Ec2Instance: Type: AWS::EC2::Instance Properties: SecurityGroups: - !Ref InstanceSecurityGroup ImageId: ami-1234567890abcdef0 InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Enable SSH access via port 22 SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 192.0.2.0/24 NewVolume: Type: AWS::EC2::Volume Properties: Size: 100 AvailabilityZone: !GetAtt [Ec2Instance, AvailabilityZone] MountPoint: Type: AWS::EC2::VolumeAttachment Properties: InstanceId: !Ref Ec2Instance VolumeId: !Ref NewVolume Device: /dev/sdh

進入ルールを持つセキュリティグループの作成

以下のサンプルスニペットは、AWS CloudFormation を使用して特定の進入ルールでセキュリティグループを設定する方法を示しています。

SSH と HTTP アクセスの進入ルールを使用してセキュリティグループを作成します。

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

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

セキュリティグループの詳細は、「Linux インスタンス用の Amazon EC2 セキュリティグループ」または「Windows インスタンス用 Amazon EC2 セキュリティグループ」を参照してください。

JSON

"SecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Allow connections from specified source security group", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "SourceSecurityGroupName": "MyAdminSecurityGroup", "SourceSecurityGroupOwnerId": "1111-2222-3333" }, { "IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "SourceSecurityGroupName": { "Ref": "MySecurityGroupCreatedInCFNTemplate" } } ] } }

YAML

SecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Allow connections from specified source security group SecurityGroupIngress: - IpProtocol: tcp FromPort: '22' ToPort: '22' SourceSecurityGroupName: MyAdminSecurityGroup SourceSecurityGroupOwnerId: '1111-2222-3333' - IpProtocol: tcp FromPort: '80' ToPort: '80' SourceSecurityGroupName: Ref: MySecurityGroupCreatedInCFNTemplate

指定された CIDR 範囲からの HTTP と SSH アクセスの進入ルールを使用してセキュリティグループを作成します。

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

セキュリティグループの詳細は、「Linux インスタンス用の Amazon EC2 セキュリティグループ」または「Windows インスタンス用 Amazon EC2 セキュリティグループ」を参照してください。

JSON

"ServerSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Allow connections from specified CIDR ranges", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "CidrIp": "192.0.2.0/24" }, { "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "192.0.2.0/24" } ] } }

YAML

ServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow connections from specified CIDR ranges SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 192.0.2.0/24 - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 192.0.2.0/24

進入ルールを使用して相互参照セキュリティグループを作成する

次のスニペットは、AWS::EC2::SecurityGroup リソースを使用して、SGroup1SGroup2 の 2 つの Amazon EC2 セキュリティグループを作成します。2 つのセキュリティグループ間の通信を許可する進入ルールは、AWS::EC2::SecurityGroupIngress リソースを使用して作成されます。SGroup1Ingress は、送信元セキュリティグループ SGroup2 からポート 80 で受信 TCP トラフィックを許可する SGroup1 の進入ルールを確立します。SGroup2Ingress は、送信元セキュリティグループ SGroup1 からのポート 80 への着信 TCP トラフィックを許可する SGroup2 の進入ルールを確立します。

JSON

"SGroup1": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "EC2 instance access" } }, "SGroup2": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "EC2 instance access" } }, "SGroup1Ingress": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupName": { "Ref": "SGroup1" }, "IpProtocol": "tcp", "ToPort": "80", "FromPort": "80", "SourceSecurityGroupName": { "Ref": "SGroup2" } } }, "SGroup2Ingress": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupName": { "Ref": "SGroup2" }, "IpProtocol": "tcp", "ToPort": "80", "FromPort": "80", "SourceSecurityGroupName": { "Ref": "SGroup1" } } }

YAML

SGroup1: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: EC2 Instance access SGroup2: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: EC2 Instance access SGroup1Ingress: Type: AWS::EC2::SecurityGroupIngress Properties: GroupName: !Ref SGroup1 IpProtocol: tcp ToPort: 80 FromPort: 80 SourceSecurityGroupName: !Ref SGroup2 SGroup2Ingress: Type: AWS::EC2::SecurityGroupIngress Properties: GroupName: !Ref SGroup2 IpProtocol: tcp ToPort: 80 FromPort: 80 SourceSecurityGroupName: !Ref SGroup1

セキュリティグループの進入ルールを使用して Elastic Load Balancer を作成する

次のテンプレートは、指定されたアベイラビリティゾーンに AWS::ElasticLoadBalancing::LoadBalancer リソースを作成します。AWS::ElasticLoadBalancing::LoadBalancer リソースは、ポート 80 で HTTP トラフィックを受信し、同じくポート 80 のインスタンスにリクエストを転送するように設定されています。Elastic Load Balancer は、インスタンス間で受信 HTTP トラフィックの負荷を分散します。

さらに、このテンプレートは、ロードバランサーに関連付けられた AWS::EC2::SecurityGroup リソースを生成します。このセキュリティグループは、ポート 80 での着信 TCP トラフィックを許可する、ELB ingress group という 1 つの進入ルールを使用して作成されます。この進入ルールのソースは、ロードバランサーリソースから属性を取得する Fn::GetAtt 関数を使用して定義されます。SourceSecurityGroupOwnerIdFn::GetAtt を使用してロードバランサーのソースセキュリティグループの OwnerAlias を取得します。SourceSecurityGroupNameFn::Getatt を使用して ELB のソースセキュリティグループの GroupName を取得します。

この設定により、ELB とインスタンス間の安全な通信が保証されます。

ロードバランシングの詳細については、「Elastic Load Balancing ユーザーガイド」を参照してください。

JSON

{ "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

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