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