Kanji
・ Cloud engineer / freelance ・ Born in 1993 ・ Born in Ehime Prefecture / Lives in Shibuya-ku, Tokyo ・ AWS history 5 years Profile details
Table of Contents
cfn-guard validate \ --rules ~/cis-aws-benchmark-level-1.guard \ --data ./template.yml
The following CloudFormation template creates a VPC.
You can customize the VPC configuration using these parameters:
DestinationVPCFlowLogBucketName
EnableCloudWatchLogsVPCFlowLog
NatGatewayNum
The CIDR blocks for the VPC and subnets are defined in the Mappings section. Please modify them to fit your design.
VPC endpoints and security groups are not included in this template.
```yaml
AWSTemplateFormatVersion: 2010-09-09 Description: template.yml Parameters: DestinationVPCFlowLogBucketName: Type: String Default: “”
EnableCloudWatchLogsVPCFlowLog: Type: String AllowedValues: - ‘true’ - ‘false’ Default: ‘false’
NatGatewayNum: Type: String AllowedValues: - ‘0’ - ‘1’ - ‘2’ Default: ‘0’
Conditions: CreateNatGateway: !Not [ !Equals [ !Ref NatGatewayNum, ‘0’ ] ] UseNatGateway1: !Or [ !Equals [ !Ref NatGatewayNum, ‘1’ ], !Equals [ !Ref NatGatewayNum, ‘2’ ] ] UseNatGateway2: !Equals [ !Ref NatGatewayNum, ‘2’ ] EnableVPCFlowLog: !Or [ !Not [ !Equals [ !Ref DestinationVPCFlowLogBucketName, “” ] ], !Equals [ !Ref EnableCloudWatchLogsVPCFlowLog, ‘true’ ] ] EnableS3VPCFlowLog: !Not [ !Equals [!Ref DestinationVPCFlowLogBucketName, “” ] ] EnableCloudWatchLogsVPCFlowLog: !Not [ !Equals [!Ref EnableCloudWatchLogsVPCFlowLog, ‘false’ ] ]
Mappings: VPC: VPC1: CIDR: 10.0.0.0/16
Subnet: PublicSubnet1: CIDR: 10.0.0.0/20 PublicSubnet2: CIDR: 10.0.16.0/20 PrivateSubnet1: CIDR: 10.0.32.0/20 PrivateSubnet2: CIDR: 10.0.48.0/20 ProtectedSubnet1: CIDR: 10.0.64.0/22 ProtectedSubnet2: CIDR: 10.0.68.0/22
Resources: VPC1: Type: AWS::EC2::VPC Properties: CidrBlock: !FindInMap [ VPC, VPC1, CIDR ] EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: sample-vpc
InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: sample-igw
VPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC1 InternetGatewayId: !Ref InternetGateway
PublicSubnet1: Type: AWS::EC2::Subnet Metadata: cfn_nag: rules_to_suppress: - id: W33 reason: “This is a public subnet.” Properties: VpcId: !Ref VPC1 CidrBlock: !FindInMap [ Subnet, PublicSubnet1, CIDR ] AvailabilityZone: !Select [ 0, !GetAZs ’’ ] MapPublicIpOnLaunch: true Tags: - Key: Name Value: sample-public1
PublicSubnet2: Type: AWS::EC2::Subnet Metadata: cfn_nag: rules_to_suppress: - id: W33 reason: “This is a public subnet.” Properties: VpcId: !Ref VPC1 CidrBlock: !FindInMap [ Subnet, PublicSubnet2, CIDR ] AvailabilityZone: !Select [ 1, !GetAZs ’’ ] MapPublicIpOnLaunch: true Tags: - Key: Name Value: sample-public2
PrivateSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC1 CidrBlock: !FindInMap [ Subnet, PrivateSubnet1, CIDR ] AvailabilityZone: !Select [ 0, !GetAZs ’’ ] MapPublicIpOnLaunch: false Tags: - Key: Name Value: sample-private1
PrivateSubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC1 CidrBlock: !FindInMap [ Subnet, PrivateSubnet2, CIDR ] AvailabilityZone: !Select [ 1, !GetAZs ’’ ] MapPublicIpOnLaunch: false Tags: - Key: Name Value: sample-private2
ProtectedSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC1 CidrBlock: !FindInMap [ Subnet, ProtectedSubnet1, CIDR ] AvailabilityZone: !Select [ 0, !GetAZs ’’ ] MapPublicIpOnLaunch: false Tags: - Key: Name Value: sample-protected1
ProtectedSubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC1 CidrBlock: !FindInMap [ Subnet, ProtectedSubnet2, CIDR ] AvailabilityZone: !Select [ 1, !GetAZs ’’ ] MapPublicIpOnLaunch: false Tags: - Key: Name Value: sample-protected2
NATGateway1EIP: Type: AWS::EC2::EIP Condition: UseNatGateway1 DependsOn: VPCGatewayAttachment Properties: Domain: vpc Tags: - Key: Name Value: sample-nat-eip1
NatGateway1: Type: AWS::EC2::NatGateway Condition: UseNatGateway1 Properties: AllocationId: !GetAtt NATGateway1EIP.AllocationId SubnetId: !Ref PublicSubnet1 Tags: - Key: Name Value: sample-natgw1
NATGateway2EIP: Type: AWS::EC2::EIP Condition: UseNatGateway2 DependsOn: VPCGatewayAttachment Properties: Domain: vpc Tags: - Key: Name Value: sample-nat-eip2
NatGateway2: Type: AWS::EC2::NatGateway Condition: UseNatGateway2 Properties: AllocationId: !GetAtt NATGateway2EIP.AllocationId SubnetId: !Ref PublicSubnet2 Tags: - Key: Name Value: sample-natgw2
PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC1 Tags: - Key: Name Value: sample-public-rt
PublicRoute: Type: AWS::EC2::Route DependsOn: VPCGatewayAttachment Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway
PublicSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet1 RouteTableId: !Ref PublicRouteTable
PublicSubnet2RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet2 RouteTableId: !Ref PublicRouteTable
PrivateSubnet1RouteTable: Type: AWS::EC2::RouteTable Condition: CreateNatGateway Properties: VpcId: !Ref VPC1 Tags: - Key: Name Value: sample-private-rt
PrivateSubnet1Route: Type: AWS::EC2::Route Condition: CreateNatGateway Properties: RouteTableId: !Ref PrivateSubnet1RouteTable DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !If [ UseNatGateway1, !Ref NatGateway1, !Ref NatGateway2 ]
PrivateSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Condition: CreateNatGateway Properties: SubnetId: !Ref PrivateSubnet1 RouteTableId: !Ref PrivateSubnet1RouteTable
PrivateSubnet2RouteTable: Type: AWS::EC2::RouteTable Condition: CreateNatGateway Properties: VpcId: !Ref VPC1 Tags: - Key: Name Value: sample-private-rt
PrivateSubnet2Route: Type: AWS::EC2::Route Condition: CreateNatGateway Properties: RouteTableId: !Ref PrivateSubnet2RouteTable DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !If [ UseNatGateway2, !Ref NatGateway2, !Ref NatGateway1 ]
PrivateSubnet2RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Condition: CreateNatGateway Properties: SubnetId: !Ref PrivateSubnet2 RouteTableId: !Ref PrivateSubnet2RouteTable
ProtectedRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC1 Tags: - Key: Name Value: sample-protected-rt
ProtectedSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref ProtectedSubnet1 RouteTableId: !Ref ProtectedRouteTable
ProtectedSubnet2RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref ProtectedSubnet2 RouteTableId: !Ref ProtectedRouteTable
CustomNetworkAcl: Type: AWS::EC2::NetworkAcl Properties: VpcId: !Ref VPC1 Tags: - Key: Name Value: sample-custom-nacl
CustomNetworkAclEntryInbound: Type: AWS::EC2::NetworkAclEntry Metadata: cfn_nag: rules_to_suppress: - id: W66 reason: “This rule allows all inbound traffic, which is necessary for the VPC to function properly.” Properties: NetworkAclId: !Ref CustomNetworkAcl RuleNumber: 100 Protocol: -1 RuleAction: allow Egress: false CidrBlock: 0.0.0.0/0
CustomNetworkAclEntryOutbound: Type: AWS::EC2::NetworkAclEntry Metadata: cfn_nag: rules_to_suppress: - id: W66 reason: “This rule allows all outbound traffic, which is necessary for the VPC to function properly.” Properties: NetworkAclId: !Ref CustomNetworkAcl RuleNumber: 100 Protocol: -1 RuleAction: allow Egress: true CidrBlock: 0.0.0.0/0
NaclAssociationPublicSubnet1: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref PublicSubnet1 NetworkAclId: !Ref CustomNetworkAcl
NaclAssociationPublicSubnet2: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref PublicSubnet2 NetworkAclId: !Ref CustomNetworkAcl
NaclAssociationPrivateSubnet1: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref PrivateSubnet1 NetworkAclId: !Ref CustomNetworkAcl
NaclAssociationPrivateSubnet2: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref PrivateSubnet2 NetworkAclId: !Ref CustomNetworkAcl
NaclAssociationProtectedSubnet1: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref ProtectedSubnet1 NetworkAclId: !Ref CustomNetworkAcl
NaclAssociationProtectedSubnet2: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref ProtectedSubnet2 NetworkAclId: !Ref CustomNetworkAcl
S3FlowLog: Type: AWS::EC2::FlowLog Condition: EnableS3VPCFlowLog Properties: ResourceId: !Ref VPC1 ResourceType: VPC TrafficType: ALL LogDestinationType: s3 LogDestination: !Sub ‘arn:aws:s3:::${DestinationVPCFlowLogBucketName}’ Tags: - Key: Name Value: sample-vpc-s3-flow-log
CloudWatchLogsFlowLog: Type: AWS::EC2::FlowLog Condition: EnableCloudWatchLogsVPCFlowLog Properties: ResourceId: !Ref VPC1 ResourceType: VPC TrafficType: ALL LogDestinationType: cloud-watch-logs LogDestination: !Sub ‘arn:aws:logs:ap-northeast-1:${AWS::AccountId}:log-group:/aws/vpc/flow-logs’ Tags: - Key: Name Value: sample-vpc-cloudwatch-logs-flow-log
FlowLogsIAMRole: Type: AWS::IAM::Role Condition: EnableVPCFlowLog Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: “IAM role name is specified as a fixed value.” guard: SuppressedRules: - IAM_NO_INLINE_POLICY_CHECK Properties: RoleName: sample-flow-logs-role AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - vpc-flow-logs.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: FlowLogsS3Policy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - s3:PutObject Resource: !Sub ’arn:aws:s3::: ${DestinationVPCFlowLogBucketName}/*' - PolicyName: FlowLogsCloudWatchLogsPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents - logs:DescribeLogGroups - logs:DescribeLogStreams Resource: !Sub "arn:aws:logs:ap-northeast-1:$ {AWS::AccountId}:log-group:/aws/vpc/*”
Outputs: VPCId: Value: !Ref VPC1 Export: Name: SampleVPCId
PublicSubnet1Id: Value: !Ref PublicSubnet1 Export: Name: SamplePublicSubnet1Id
PublicSubnet2Id: Value: !Ref PublicSubnet2 Export: Name: SamplePublicSubnet2Id
PrivateSubnet1Id: Value: !Ref PrivateSubnet1 Export: Name: SamplePrivateSubnet1Id
PrivateSubnet2Id: Value: !Ref PrivateSubnet2 Export: Name: SamplePrivateSubnet2Id
ProtectedSubnet1Id: Value: !Ref ProtectedSubnet1 Export: Name: SampleProtectedSubnet1Id
ProtectedSubnet2Id: Value: !Ref ProtectedSubnet2 Export: Name: SampleProtectedSubnet2Id