実践CloudFormation VPC編


#これまでのおさらい

これまではハンズオンでスタックを作成して、いろいろと体験していただいたと思います。

そこから実践で作成していくにあたってどのように構築していくのか？
実践形式でいろいろと実施していきましょう。

*注意！！
ここからは東京リージョンでスタックを作成していきます！！

さてここからはVPC編と言うことで、まずはどういった構成を作るのか？と言うところからスタートしましょう。

![VPC (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/c4e8dd42-daa1-2c87-7929-d256cc5f9a2a.png)

今回構築するのは
VPC
PublicSubnet2つ
PrivateSubnet2つ
InternetGateway
RouteTable2つ
NetworkACL2つ

になります。

さてまずは

ソースコードから

```VPC.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: 
  VPC and Subnet Create

# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------# 
Metadata: 
  "AWS::CloudFormation::Interface": 
    ParameterGroups: 
      - Label: 
          default: "Project Name Prefix"
        Parameters: 
          - PJPrefix
      - Label: 
          default: "Network Configuration"
        Parameters: 
          - VPCCIDR
          - PublicSubnetACIDR
          - PublicSubnetCCIDR
          - PrivateSubnetACIDR
          - PrivateSubnetCCIDR
    ParameterLabels: 
      VPCCIDR: 
        default: "VPC CIDR"
      PublicSubnetACIDR: 
        default: "PublicSubnetA CIDR"
      PublicSubnetCCIDR: 
        default: "PublicSubnetC CIDR"
      PrivateSubnetACIDR: 
        default: "PrivateSubnetA CIDR"
      PrivateSubnetCCIDR: 
        default: "PrivateSubnetC CIDR"
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------# 
Parameters:
  PJPrefix:
    Description: Enter a prefix of this system.
    Type: String
    Default: "test"
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9][ -~]*"
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.

  VPCCIDR:
    Type: String
    Default: "10.3.0.0/16"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

  PublicSubnetACIDR:
    Type: String
    Default: "10.3.10.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

  PublicSubnetCCIDR:
    Type: String
    Default: "10.3.20.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.


  PrivateSubnetACIDR:
    Type: String
    Default: "10.3.200.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

  PrivateSubnetCCIDR:
    Type: String
    Default: "10.3.201.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

Resources:
# ------------------------------------------------------------#
#  VPC
# ------------------------------------------------------------#
# VPC Create
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: !Ref VPCCIDR
      EnableDnsSupport: "true"
      EnableDnsHostnames: "false"
      InstanceTenancy: default
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-vpc"

# InternetGateway Create
  InternetGateway: 
    Type: "AWS::EC2::InternetGateway"
    Properties: 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-igw"

# IGW Attach
  InternetGatewayAttachment: 
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties: 
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC 

# ------------------------------------------------------------#
#  Subnet
# ------------------------------------------------------------#          
# Public SubnetA Create
  PublicSubnetA: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: !Ref PublicSubnetACIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-public-subnet-a"

# Public SubnetC Create
  PublicSubnetC: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1c"
      CidrBlock: !Ref PublicSubnetCCIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-public-subnet-c"


# Private SubnetA Create
  PrivateSubnetA: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: !Ref PrivateSubnetACIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-subnet-a"

# Private SubnetC Create
  PrivateSubnetC: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1c"
      CidrBlock: !Ref PrivateSubnetCCIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-subnet-c"

# ------------------------------------------------------------#
#  NetworkACL 事前に作成していてsubnetに対してアクセスコントロールを実施したい時に設定する
# ------------------------------------------------------------#
# PublicNetworkAcl Create
  PublicNetworkAcl:
    Type: "AWS::EC2::NetworkAcl"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${PJPrefix}-public

# PrivateNetworkAcl Create
  PrivateNetworkAcl:
    Type: "AWS::EC2::NetworkAcl"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${PJPrefix}-private

# ------------------------------------------------------------#
#  NetworkACL Entry
# ------------------------------------------------------------#          
# PublicNetworkAclEntryTrue Create
  PublicNetworkAclEntryTrue:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: true
      NetworkAclId: !Ref PublicNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100

# PublicNetworkAclEntryFalse Create
  PublicNetworkAclEntryFalse:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: false
      NetworkAclId: !Ref PublicNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100

# PrivateNetworkAclEntryTrue Create
  PrivateNetworkAclEntryTrue:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: true
      NetworkAclId: !Ref PrivateNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100

# PrivateNetworkAclEntryFalse Create
  PrivateNetworkAclEntryFalse:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: false
      NetworkAclId: !Ref PrivateNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100
# ------------------------------------------------------------#
#  RouteTable
# ------------------------------------------------------------#
# Public RouteTableA Create
  PublicRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${PJPrefix}-public-route"

# Private RouteTableA Create
  PrivateRouteTableA: 
    Type: "AWS::EC2::RouteTable"
    Properties: 
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-route-a"

# Private RouteTableC Create
  PrivateRouteTableC: 
    Type: "AWS::EC2::RouteTable"
    Properties: 
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-route-c"

# ------------------------------------------------------------#
# Routing
# ------------------------------------------------------------# 
# PublicRouteA Create
  PublicRoute:
    Type: "AWS::EC2::Route"
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

# ------------------------------------------------------------#
# RouteTable Associate
# ------------------------------------------------------------# 
# PublicRouteTable Associate SubnetA
  PublicSubnetARouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PublicSubnetA 
      RouteTableId: !Ref PublicRouteTable

# PublicRouteTable Associate SubnetC
  PublicSubnetCRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PublicSubnetC 
      RouteTableId: !Ref PublicRouteTable

# PrivateRouteTable Associate SubnetA
  PrivateSubnetARouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PrivateSubnetA
      RouteTableId: !Ref PrivateRouteTableA 

# PrivateRouteTable Associate SubnetC
  PrivateSubnetCRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PrivateSubnetC
      RouteTableId: !Ref PrivateRouteTableC

# ------------------------------------------------------------#
# Network Association
# ------------------------------------------------------------#
# PrivateSubnetANetworkAssociation Create
  PrivateSubnetANetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PrivateSubnetA
      NetworkAclId: !Ref PrivateNetworkAcl

# PrivateSubnetCNetworkAssociation Create
  PrivateSubnetCNetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PrivateSubnetC
      NetworkAclId: !Ref PrivateNetworkAcl

# PublicSubnetANetworkAssociation Create
  PublicSubnetANetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PublicSubnetC
      NetworkAclId: !Ref PublicNetworkAcl

# PublicSubnetCNetworkAssociation Create
  PublicSubnetCNetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PublicSubnetC
      NetworkAclId: !Ref PublicNetworkAcl

# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#                
Outputs:
# VPC
  VPC:
    Value: !Ref VPC
    Export:
      Name: !Sub "${PJPrefix}-vpc"

  VPCCIDR:
    Value: !Ref VPCCIDR
    Export:
      Name: !Sub "${PJPrefix}-vpc-cidr"

# Subnet
  PublicSubnetA:
    Value: !Ref PublicSubnetA
    Export:
      Name: !Sub "${PJPrefix}-public-subnet-a"

  PublicSubnetACIDR:
    Value: !Ref PublicSubnetACIDR
    Export:
      Name: !Sub "${PJPrefix}-public-subnet-a-cidr"

  PublicSubnetC:
    Value: !Ref PublicSubnetC
    Export:
      Name: !Sub "${PJPrefix}-public-subnet-c"

  PublicSubnetCCIDR:
    Value: !Ref PublicSubnetCCIDR
    Export:
      Name: !Sub "${PJPrefix}-public-subnet-c-cidr"

  PrivateSubnetA:
    Value: !Ref PrivateSubnetA
    Export:
      Name: !Sub "${PJPrefix}-private-subnet-a"

  PrivateSubnetACIDR:
    Value: !Ref PrivateSubnetACIDR
    Export:
      Name: !Sub "${PJPrefix}-private-subnet-a-cidr"

  PrivateSubnetC:
    Value: !Ref PrivateSubnetC
    Export:
      Name: !Sub "${PJPrefix}-private-subnet-c"

  PrivateSubnetCCIDR:
    Value: !Ref PrivateSubnetCCIDR
    Export:
      Name: !Sub "${PJPrefix}-private-subnet-c-cidr"

# Route
  PublicRouteTable:
    Value: !Ref PublicRouteTable
    Export:
      Name: !Sub "${PJPrefix}-public-route"

  PrivateRouteTableA:
    Value: !Ref PrivateRouteTableA
    Export:
      Name: !Sub "${PJPrefix}-private-route-a"

  PrivateRouteTableC:
    Value: !Ref PrivateRouteTableC
    Export:
      Name: !Sub "${PJPrefix}-private-route-c"
```

#スタックを作成しようとするとこんな感じ
*リージョンは東京です。

![スクリーンショット 2020-08-31 20.28.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/4b83d7e6-d237-7f4d-8ab4-fe2d4534a058.png)

パラメータとして設定されているのは
・PJPrefix
・VPC CIDR
・PublicSubnetA CIDR
・PublicSubnetC CIDR
・PrivateSubnetA CIDR
・PrivateSubnetC CIDR

の6つです。
それではこのパラメータをどのように設定しているのか見ていきましょう。

## Parametersの中身
```VPC.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: 
  VPC and Subnet Create

# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------# 
Metadata: 
  "AWS::CloudFormation::Interface": 
    ParameterGroups: 
      - Label: 
          default: "Project Name Prefix"
        Parameters: 
          - PJPrefix
      - Label: 
          default: "Network Configuration"
        Parameters: 
          - VPCCIDR
          - PublicSubnetACIDR
          - PublicSubnetCCIDR
          - PrivateSubnetACIDR
          - PrivateSubnetCCIDR
    ParameterLabels: 
      VPCCIDR: 
        default: "VPC CIDR"
      PublicSubnetACIDR: 
        default: "PublicSubnetA CIDR"
      PublicSubnetCCIDR: 
        default: "PublicSubnetC CIDR"
      PrivateSubnetACIDR: 
        default: "PrivateSubnetA CIDR"
      PrivateSubnetCCIDR: 
        default: "PrivateSubnetC CIDR"
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------# 
Parameters:
  PJPrefix:
    Description: Enter a prefix of this system.
    Type: String
    Default: "test"
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9][ -~]*"
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.

  VPCCIDR:
    Type: String
    Default: "10.3.0.0/16"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

  PublicSubnetACIDR:
    Type: String
    Default: "10.3.10.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

  PublicSubnetCCIDR:
    Type: String
    Default: "10.3.20.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.


  PrivateSubnetACIDR:
    Type: String
    Default: "10.3.200.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

  PrivateSubnetCCIDR:
    Type: String
    Default: "10.3.201.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

```

おっと早速謎な値が出てきたと思います。

まずは一つずつ見ていきます。

```VPC.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: 
  VPC and Subnet Create
```

まず、この

```yaml

AWSTemplateFormatVersion: "2010-09-09"
```

この部分ですがCloudFormationを作成する際にはあってもなくてもいいのですが、
僕は個人的につけています。
なくてもテンプレート展開可能です。

```yaml
Description: 
  VPC and Subnet Create
```

ここはCFNテンプレート全体の説明を記載します。
このテンプレートってなんだっけ？という部分になります。

### メタデータ

```yaml
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------# 
Metadata: 
  "AWS::CloudFormation::Interface": 
    ParameterGroups: 
      - Label: 
          default: "Project Name Prefix"
        Parameters: 
          - PJPrefix
      - Label: 
          default: "Network Configuration"
        Parameters: 
          - VPCCIDR
          - PublicSubnetACIDR
          - PublicSubnetCCIDR
          - PrivateSubnetACIDR
          - PrivateSubnetCCIDR
    ParameterLabels: 
      VPCCIDR: 
        default: "VPC CIDR"
      PublicSubnetACIDR: 
        default: "PublicSubnetA CIDR"
      PublicSubnetCCIDR: 
        default: "PublicSubnetC CIDR"
      PrivateSubnetACIDR: 
        default: "PrivateSubnetA CIDR"
      PrivateSubnetCCIDR: 
        default: "PrivateSubnetC CIDR"
```

ここはメタデータの部分です。
使う用途としては
パラメータの選択をまとめる形となります。


### パラメータ

```yaml
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------# 
Parameters:
  PJPrefix:
    Description: Enter a prefix of this system.
    Type: String
    Default: "test"
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9][ -~]*"
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.

  VPCCIDR:
    Type: String
    Default: "10.3.0.0/16"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

  PublicSubnetACIDR:
    Type: String
    Default: "10.3.10.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

  PublicSubnetCCIDR:
    Type: String
    Default: "10.3.20.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.


  PrivateSubnetACIDR:
    Type: String
    Default: "10.3.200.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

  PrivateSubnetCCIDR:
    Type: String
    Default: "10.3.201.0/24"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

```

ここはパラメータの部分になります。
ここには入力して
リソースなどに渡すことができます。
これをCFNではよく使います。


## リソースの中身

```yaml
Resources:
# ------------------------------------------------------------#
#  VPC
# ------------------------------------------------------------#
# VPC Create
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: !Ref VPCCIDR
      EnableDnsSupport: "true"
      EnableDnsHostnames: "false"
      InstanceTenancy: default
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-vpc"

# InternetGateway Create
  InternetGateway: 
    Type: "AWS::EC2::InternetGateway"
    Properties: 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-igw"

# IGW Attach
  InternetGatewayAttachment: 
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties: 
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC 

# ------------------------------------------------------------#
#  Subnet
# ------------------------------------------------------------#          
# Public SubnetA Create
  PublicSubnetA: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: !Ref PublicSubnetACIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-public-subnet-a"

# Public SubnetC Create
  PublicSubnetC: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1c"
      CidrBlock: !Ref PublicSubnetCCIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-public-subnet-c"


# Private SubnetA Create
  PrivateSubnetA: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: !Ref PrivateSubnetACIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-subnet-a"

# Private SubnetC Create
  PrivateSubnetC: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1c"
      CidrBlock: !Ref PrivateSubnetCCIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-subnet-c"

# ------------------------------------------------------------#
#  NetworkACL 事前に作成していてsubnetに対してアクセスコントロールを実施したい時に設定する
# ------------------------------------------------------------#
# PublicNetworkAcl Create
  PublicNetworkAcl:
    Type: "AWS::EC2::NetworkAcl"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${PJPrefix}-public

# PrivateNetworkAcl Create
  PrivateNetworkAcl:
    Type: "AWS::EC2::NetworkAcl"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${PJPrefix}-private

# ------------------------------------------------------------#
#  NetworkACL Entry
# ------------------------------------------------------------#          
# PublicNetworkAclEntryTrue Create
  PublicNetworkAclEntryTrue:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: true
      NetworkAclId: !Ref PublicNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100

# PublicNetworkAclEntryFalse Create
  PublicNetworkAclEntryFalse:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: false
      NetworkAclId: !Ref PublicNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100

# PrivateNetworkAclEntryTrue Create
  PrivateNetworkAclEntryTrue:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: true
      NetworkAclId: !Ref PrivateNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100

# PrivateNetworkAclEntryFalse Create
  PrivateNetworkAclEntryFalse:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: false
      NetworkAclId: !Ref PrivateNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100
# ------------------------------------------------------------#
#  RouteTable
# ------------------------------------------------------------#
# Public RouteTableA Create
  PublicRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${PJPrefix}-public-route"

# Private RouteTableA Create
  PrivateRouteTableA: 
    Type: "AWS::EC2::RouteTable"
    Properties: 
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-route-a"

# Private RouteTableC Create
  PrivateRouteTableC: 
    Type: "AWS::EC2::RouteTable"
    Properties: 
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-route-c"

# ------------------------------------------------------------#
# Routing
# ------------------------------------------------------------# 
# PublicRouteA Create
  PublicRoute:
    Type: "AWS::EC2::Route"
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

# ------------------------------------------------------------#
# RouteTable Associate
# ------------------------------------------------------------# 
# PublicRouteTable Associate SubnetA
  PublicSubnetARouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PublicSubnetA 
      RouteTableId: !Ref PublicRouteTable

# PublicRouteTable Associate SubnetC
  PublicSubnetCRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PublicSubnetC 
      RouteTableId: !Ref PublicRouteTable

# PrivateRouteTable Associate SubnetA
  PrivateSubnetARouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PrivateSubnetA
      RouteTableId: !Ref PrivateRouteTableA 

# PrivateRouteTable Associate SubnetC
  PrivateSubnetCRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PrivateSubnetC
      RouteTableId: !Ref PrivateRouteTableC

# ------------------------------------------------------------#
# Network Association
# ------------------------------------------------------------#
# PrivateSubnetANetworkAssociation Create
  PrivateSubnetANetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PrivateSubnetA
      NetworkAclId: !Ref PrivateNetworkAcl

# PrivateSubnetCNetworkAssociation Create
  PrivateSubnetCNetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PrivateSubnetC
      NetworkAclId: !Ref PrivateNetworkAcl

# PublicSubnetANetworkAssociation Create
  PublicSubnetANetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PublicSubnetC
      NetworkAclId: !Ref PublicNetworkAcl

# PublicSubnetCNetworkAssociation Create
  PublicSubnetCNetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PublicSubnetC
      NetworkAclId: !Ref PublicNetworkAcl

```

ここがリソースになります。
今回作ろうとしている
1. VPC
2. インターネットゲートウェイ
3. VPCにインターネットゲートウェイをアタッチする
4. サブネットを作る
5. ネットワークACLを作る
6. ネットワークACLのインプットのルールとアウトプットのルールを作ってネットワークACLにアタッチする
7. ルートテーブルを作る
8. ルートテーブルをインターネットゲートウェイにアタッチする
9. サブネットとルートテーブルを関連付ける
10. サブネットとネットワークACLを関連付ける

というのが一連の流れです。
ここの項目は分割しても大丈夫です。ですが分割する際はエクスポートをしないといけないのでその点が注意です。

![VPC (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/c4e8dd42-daa1-2c87-7929-d256cc5f9a2a.png)

重要なのが、この構成を作ろうとするときに
それぞれ単品を作ってセットと認識させないとうまく構成ができないという現象になります。
VPCはインターネットゲートウェイと紐付いて初めてアクセスでき
インターネットゲートウェイはルートテーブルと紐付いてこそアクセスができ。

といった、それぞれ別のものをつないでこそ、「環境」ができます。
*ここで何か渾身のネタをいれる（松本）
「つまりセルは最初の段階では弱いので人造人間を取り込み完全体になるのだ！！（cv:若本規夫）」
*ここでセルの画像を表示

## 1. VPC

```yaml
# ------------------------------------------------------------#
#  VPC
# ------------------------------------------------------------#
# VPC Create
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: !Ref VPCCIDR
      EnableDnsSupport: "true"
      EnableDnsHostnames: "false"
      InstanceTenancy: default
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-vpc"
```

この部分でVPCを作成することができます。
[ドキュメントはこちら](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html)

結構このドキュメントをじっくり読みことが必要になります。

さてここで一つ気になる部分をご紹介

```yaml
# ------------------------------------------------------------#
#  VPC
# ------------------------------------------------------------#
# VPC Create
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: !Ref VPCCIDR ←ここ
      EnableDnsSupport: "true"
      EnableDnsHostnames: "false"
      InstanceTenancy: default
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-vpc"
```

この`!Ref VPCCIDR`って何？となると思います。

まずここを解説する前に`!Ref`とはなんなのか？みていきましょう

[Refに関するドキュメント](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html)

まず`!`はyamlで書くときの短縮系の書き方になります。
正式に書く際は

`Ref: logicalName`

となります。
そしてこのRefが何を表すかというと
論理名前を取得することができます。

さてVPCCIDRってなんだっけ？
となるかと思います。
パラメータのところでVPCCIDRを設定したところがあったと思います

```yaml
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------# 
Parameters:
  PJPrefix:
    Description: Enter a prefix of this system.
    Type: String
    Default: "test"
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9][ -~]*"
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.

  VPCCIDR:←ここ
    Type: String
    Default: "10.3.0.0/16"
    MinLength: 9
    MaxLength: 18
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Min characters 9, Max characters 18.

```

つまりパラメータで設定した部分を呼び出ししますよという感じです。
イメージとしては変数が一番掴みやすいのかなと思っています

さて続きをみていきましょう

次に気になるポイントとして

```yaml
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: !Ref VPCCIDR
      EnableDnsSupport: "true"
      EnableDnsHostnames: "false"
      InstanceTenancy: default
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-vpc"←ここ
```
!Subって何？ってなると思われます。

このSubは変数を文字列の中に埋め込むことができた機能があったと思います

```JavaScript
let sample = 'test';
console.log('test${sample}')
```

こういうのありましたよね？
これです。

あとはこのPJPrefixはパラメータで指定されています。

```yaml
PJPrefix:
    Description: Enter a prefix of this system.
    Type: String
    Default: "test"
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9][ -~]*"
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
```

今回はプロジェクト名を変数として実施しています。
なのでこれからこのVPCのタグはPJPrefixの名前-vpc
という名前になります。

## 2. インターネットゲートウェイ

```yaml
# InternetGateway Create
  InternetGateway: 
    Type: "AWS::EC2::InternetGateway"
    Properties: 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-igw"
```

インターネットからVPCにアクセスするにはインターネットゲートウェイが必要です。
[ドキュメント](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html)

## 3. VPCにインターネットゲートウェイをアタッチする

```yaml
# IGW Attach
  InternetGatewayAttachment: 
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties: 
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC
```

作成したインターネットゲートウェイはVPCにつなげて初めてインターネットからアクセスできます。
[ドキュメント](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html)


## 4. サブネットを作る

```yaml
# ------------------------------------------------------------#
#  Subnet
# ------------------------------------------------------------#          
# Public SubnetA Create
  PublicSubnetA: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: !Ref PublicSubnetACIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-public-subnet-a"

# Public SubnetC Create
  PublicSubnetC: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1c"
      CidrBlock: !Ref PublicSubnetCCIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-public-subnet-c"


# Private SubnetA Create
  PrivateSubnetA: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: !Ref PrivateSubnetACIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-subnet-a"

# Private SubnetC Create
  PrivateSubnetC: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1c"
      CidrBlock: !Ref PrivateSubnetCCIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-subnet-c"
```

サブネットはこちら。
[ドキュメント](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html)

もちろんサブネットはVPCの中につくるのでVPCが必要で
CidrBlockが必要です。

さてエドワードエルリックのように勘のいいみなさんはお気づきだと思います。

CloudFormationはそもそもの仕組みが理解できていないと
構築するのが至難の技になります。

モチベーションとして
「一は全、全は一」

です。

## 5. ネットワークACLを作る

```yaml
# ------------------------------------------------------------#
#  NetworkACL 事前に作成していてsubnetに対してアクセスコントロールを実施したい時に設定する
# ------------------------------------------------------------#
# PublicNetworkAcl Create
  PublicNetworkAcl:
    Type: "AWS::EC2::NetworkAcl"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${PJPrefix}-public

# PrivateNetworkAcl Create
  PrivateNetworkAcl:
    Type: "AWS::EC2::NetworkAcl"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${PJPrefix}-private
```

ネットワークアクセスコントロールリストです。
これはVPC内に作成されて
サブネットに紐付けられます
[ネットワークアクセスコントロールリストはこちら](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-network-acls.html)
[ドキュメントはこちら](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html)

## 6. ネットワークACLのインプットのルールとアウトプットのルールを作ってネットワークACLにアタッチする

```yaml
# ------------------------------------------------------------#
#  NetworkACL Entry
# ------------------------------------------------------------#          
# PublicNetworkAclEntryTrue Create
  PublicNetworkAclEntryTrue:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: true
      NetworkAclId: !Ref PublicNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100

# PublicNetworkAclEntryFalse Create
  PublicNetworkAclEntryFalse:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: false
      NetworkAclId: !Ref PublicNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100

# PrivateNetworkAclEntryTrue Create
  PrivateNetworkAclEntryTrue:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: true
      NetworkAclId: !Ref PrivateNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100

# PrivateNetworkAclEntryFalse Create
  PrivateNetworkAclEntryFalse:
    Type: "AWS::EC2::NetworkAclEntry"
    Properties:
      CidrBlock: "0.0.0.0/0"
      Egress: false
      NetworkAclId: !Ref PrivateNetworkAcl
      Protocol: -1
      RuleAction: "allow"
      RuleNumber: 100
```

ネットワークアクセスコントロールリストのルールを作成します
[ドキュメントはこちら](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html)

## 7. ルートテーブルを作る

```yaml
# ------------------------------------------------------------#
#  RouteTable
# ------------------------------------------------------------#
# Public RouteTableA Create
  PublicRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${PJPrefix}-public-route"

# Private RouteTableA Create
  PrivateRouteTableA: 
    Type: "AWS::EC2::RouteTable"
    Properties: 
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-route-a"

# Private RouteTableC Create
  PrivateRouteTableC: 
    Type: "AWS::EC2::RouteTable"
    Properties: 
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-private-route-c"
```

[ルートテーブルはこちら](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html)

## 8. ルートテーブルをインターネットゲートウェイにアタッチする

```yaml
# ------------------------------------------------------------#
# Routing
# ------------------------------------------------------------# 
# PublicRouteA Create
  PublicRoute:
    Type: "AWS::EC2::Route"
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway
```

[ルートテーブルはルートを指定しないと動きません](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html)

## 9. サブネットとルートテーブルを関連付ける

```yaml
# ------------------------------------------------------------#
# RouteTable Associate
# ------------------------------------------------------------# 
# PublicRouteTable Associate SubnetA
  PublicSubnetARouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PublicSubnetA 
      RouteTableId: !Ref PublicRouteTable

# PublicRouteTable Associate SubnetC
  PublicSubnetCRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PublicSubnetC 
      RouteTableId: !Ref PublicRouteTable

# PrivateRouteTable Associate SubnetA
  PrivateSubnetARouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PrivateSubnetA
      RouteTableId: !Ref PrivateRouteTableA 

# PrivateRouteTable Associate SubnetC
  PrivateSubnetCRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PrivateSubnetC
      RouteTableId: !Ref PrivateRouteTableC
```

[サブネットにルートテーブルを紐付けます](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html)


## 10. サブネットとネットワークACLを関連付ける

```yaml
# ------------------------------------------------------------#
# Network Association
# ------------------------------------------------------------#
# PrivateSubnetANetworkAssociation Create
  PrivateSubnetANetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PrivateSubnetA
      NetworkAclId: !Ref PrivateNetworkAcl

# PrivateSubnetCNetworkAssociation Create
  PrivateSubnetCNetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PrivateSubnetC
      NetworkAclId: !Ref PrivateNetworkAcl

# PublicSubnetANetworkAssociation Create
  PublicSubnetANetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PublicSubnetC
      NetworkAclId: !Ref PublicNetworkAcl

# PublicSubnetCNetworkAssociation Create
  PublicSubnetCNetworkAssociation:
    Type: "AWS::EC2::SubnetNetworkAclAssociation"
    Properties:
      SubnetId: !Ref PublicSubnetC
      NetworkAclId: !Ref PublicNetworkAcl
```

[サブネットにネットワークアクセスコントロールリストを紐付けます](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-network-acl-assoc.html)

# Output

```yaml
# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#                
Outputs:
# VPC
  VPC:
    Value: !Ref VPC
    Export:
      Name: !Sub "${PJPrefix}-vpc"

  VPCCIDR:
    Value: !Ref VPCCIDR
    Export:
      Name: !Sub "${PJPrefix}-vpc-cidr"

# Subnet
  PublicSubnetA:
    Value: !Ref PublicSubnetA
    Export:
      Name: !Sub "${PJPrefix}-public-subnet-a"

  PublicSubnetACIDR:
    Value: !Ref PublicSubnetACIDR
    Export:
      Name: !Sub "${PJPrefix}-public-subnet-a-cidr"

  PublicSubnetC:
    Value: !Ref PublicSubnetC
    Export:
      Name: !Sub "${PJPrefix}-public-subnet-c"

  PublicSubnetCCIDR:
    Value: !Ref PublicSubnetCCIDR
    Export:
      Name: !Sub "${PJPrefix}-public-subnet-c-cidr"

  PrivateSubnetA:
    Value: !Ref PrivateSubnetA
    Export:
      Name: !Sub "${PJPrefix}-private-subnet-a"

  PrivateSubnetACIDR:
    Value: !Ref PrivateSubnetACIDR
    Export:
      Name: !Sub "${PJPrefix}-private-subnet-a-cidr"

  PrivateSubnetC:
    Value: !Ref PrivateSubnetC
    Export:
      Name: !Sub "${PJPrefix}-private-subnet-c"

  PrivateSubnetCCIDR:
    Value: !Ref PrivateSubnetCCIDR
    Export:
      Name: !Sub "${PJPrefix}-private-subnet-c-cidr"

# Route
  PublicRouteTable:
    Value: !Ref PublicRouteTable
    Export:
      Name: !Sub "${PJPrefix}-public-route"

  PrivateRouteTableA:
    Value: !Ref PrivateRouteTableA
    Export:
      Name: !Sub "${PJPrefix}-private-route-a"

  PrivateRouteTableC:
    Value: !Ref PrivateRouteTableC
    Export:
      Name: !Sub "${PJPrefix}-private-route-c"
```

ここは出力パラメータになります。
というのもここまでにして実際にCloudFormationのスタックを実行してみましょう！！

# 実際に作ってみる

## その１

![スクリーンショット 2020-10-05 22.00.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/4bf4275b-da5f-50f1-31a8-182d7cabed62.png)

スタックの作成をクリック

## その２
![スクリーンショット 2020-10-05 22.01.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/87e0e4fa-bcea-7727-677c-085148544e31.png)

テンプレートの準備完了
テンプレートファイルのアップロード
ファイルの選択（ファイルはhandson/03_Practice_VPC/VPC.yamlになります）
次へをクリック

## その3

![スクリーンショット 2020-10-05 22.06.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/a0c3bd14-e006-af67-beee-76040e443697.png)


スタックの名前を入力
パラメータの
PJPrefix（プロジェクトの名前）を入力
VPCCIDRを入力（デフォルトのVPCネットワークを使用していなければデフォでOK）
PublicSubnetA CIDRを入力
PublicSubnetC CIDRを入力
PrivateSubnetA CIDRを入力
PrivateSubnetC CIDRを入力
(VPCのネットワークに収まるようにお願いします）
次へをクリック

## その４
![スクリーンショット 2020-10-05 22.07.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/89922100-7a76-9d5e-3ec6-5e347dbd94cf.png)


タグやIAMを指定したりその他オプションを設定できますが
今回はデフォでOKです。（解説はしませんが、興味がある方はぜひドキュメントを読んで遊んでみてください！）

次へクリック

## その5
![スクリーンショット 2020-10-05 22.08.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/d6c298c2-0f5d-3d93-eba1-2d7ccbb47d04.png)

![スクリーンショット 2020-10-05 22.08.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/6c31d460-3fdc-e21b-d2dd-f6d905d68a06.png)



レビューを確認して問題なければスタックの作成をクリック

# 注意点
ここで注意点ですが、すでにVPCやInternetGatewayの最大数に達している方は上限緩和申請が必要です。
VPC上限デフォ5つ
IGW上限デフォ5つ
サブネット上限デフォ200こです。（流石に個人でこれを上限いくのはなかなか・・・）
[ソース](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/amazon-vpc-limits.html)

## 完成

![スクリーンショット 2020-10-05 22.34.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/e5db779f-1089-1bab-b147-33e335f4a67a.png)

CREATE_COMPLETEとなれば作成成功です。
ここでエラーになるとデフォルトの設定では作成したリソースは全てロールバックで削除されます。

## リソースの確認
![スクリーンショット 2020-10-05 22.37.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/74a639cc-00be-1807-75aa-b014e22be4de.png)


タグのリソースをクリック

## 出力を確認
![スクリーンショット 2020-10-05 22.38.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253981/709af986-8f18-244c-ae73-b9a4f3cd5ae2.png)

Ouyputsで記載した内容が出力されています。

これにてVPCは完成です。
お疲れ様でした。

[SG編](https://qiita.com/kazumasamatsumo/private/bbf241619257fffeebfe)