flowchart LR
%%{init:{"theme":"neutral"}}%%
subgraph aws["AWS アカウント"]
subgraph vpc-vvvv1["VPC (10.0.0.0/16)"]
subgraph public1["sample-public1"]
NAT1@{icon: "logos:Res_Amazon-VPC_NAT-Gateway", label: "sample-natgw1", pos: "b", h: 40}
end
subgraph public2["sample-public2"]
NAT2@{icon: "logos:Res_Amazon-VPC_NAT-Gateway", label: "sample-natgw2", pos: "b", h: 40}
end
subgraph private1["sample-private1"]
EC2-1@{icon: "logos:Res_Amazon-EC2_Instance", label: "EC2 インスタンス(定義外)", pos: "b", h: 40}
end
subgraph private2["sample-private2"]
EC2-2@{icon: "logos:Res_Amazon-EC2_Instance", label: "EC2 インスタンス(定義外)", pos: "b", h: 40}
end
subgraph protected1["sample-protected-1"]
RDS1@{icon: "logos:Arch_Amazon-RDS", label: "RDS インスタンス(定義外)", pos: "b", h: 40}
end
subgraph protected2["sample-protected-2"]
RDS2@{icon: "logos:Arch_Amazon-RDS", label: "RDS インスタンス(定義外)", pos: "b", h: 40}
end
public2 ~~~ private2 ~~~ protected2
public1 ~~~ private1 ~~~ protected1
IGW@{icon: "logos:Res_Amazon-VPC_Internet-Gateway", label: "sample-igw", pos: "b", h: 40}
end
subgraph global-services1[" "]
IAMRole1@{icon: "logos:Res_AWS-Identity-Access-Management_Role", label: "sample-flow-logs-role", pos: "b", h: 40}
end
subgraph global-services2[" "]
FlowLog1@{icon: "logos:Res_Amazon-VPC_Flow-Logs", label: "sample-vpc-s3-flow-log", pos: "b", h: 40}
S3Flow1@{icon: "logos:Res_Amazon-Simple-Storage-Service_Bucket", label: "S3 バケット(定義外)", pos: "b", h: 40}
end
subgraph global-services3[" "]
FlowLog2@{icon: "logos:Res_Amazon-VPC_Flow-Logs", label: "sample-vpc-cloudwatch-logs-flow-log", pos: "b", h: 40}
CWLogs1@{icon: "logos:Res_Amazon-CloudWatch_Logs", label: "/aws/vpc/flow-logs", pos: "b", h: 40}
end
vpc-vvvv1 ~~~ global-services1
vpc-vvvv1 ~~~ global-services2
vpc-vvvv1 ~~~ global-services3
end
classDef group fill:none,stroke:none
classDef vpc fill:none,color:#0a0,stroke:#0a0
classDef public fill:#def,color:#07b,stroke:none
classDef private fill:#efe,color:#092,stroke:none
style aws fill:#fff,color:#345,stroke:#345
class vpc-vvvv1 vpc
class public1 public
class public2 public
class private1 private
class private2 private
class protected1 private
class protected2 private
class global-services1,global-services2,global-services3 group
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
FlowLogsLogGroup:
Type: AWS::Logs::LogGroup
Condition: EnableCloudWatchLogsVPCFlowLog
Properties:
LogGroupName: /aws/vpc/flow-logs
RetentionInDays: 90
Tags:
- Key: Name
Value: sample-vpc-flow-logs-log-group
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