AWS CloudFormation テンプレートの基礎

#■テンプレートの概要#
![スクリーンショット 2019-05-24 20.51.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/20c693c2-0666-6c9e-baee-1f5e1077dfa5.png)


#1.AMIからEC2インスタンスを立ち上げる#

```json
AWSTemplateFormatVersion: "2010-09-09"
Description: Create EC2 Instance
Resources:
  CreateEC2Instance:
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: ami-06a17900f024535fb
＃ImageIdは自分のAMI IDに書き換えてください。
      InstanceType: t2.micro 
```

#2.Parametersを作成し、ref関数を使い参照する#

```json

AWSTemplateFormatVersion: "2010-09-09"
Description: Create EC2 Instance
Parameters:
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
    - t1.micro
    - t2.nano
    - t2.micro
    - t2.small
    - t2.medium
    - t2.large
    ConstraintDescription: must be a valid EC2 instance type
＃Parametersでインスタンスタイプを選択できるようにする。

Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: ami-06a17900f024535fb
      InstanceType: !Ref InstanceType
＃Ref関数でParametersを参照する。
     Tags:
      - Key: Name
        Value: ec2
```

#3.Mappings関数を使い、複数のリージョンの複数のAMIから選択できるようにする#

```json
AWSTemplateFormatVersion: "2010-09-09"
Description: Create EC2 Instance
Parameters:
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
    - t1.micro
    - t2.nano
    - t2.micro
    - t2.small
    - t2.medium
    - t2.large
    ConstraintDescription: must be a valid EC2 instance type
Mappings: 
  RegionMap: 
    ap-northeast-1:
      hvm: "ami-06a17900f024535fb"
    ap-southeast-1:
      hvm: "ami-055a628643638b600"
#Mappings関数を使い、複数のリージョンの複数のAMIから選択できるようにします。東京リージョンとシンガポールリージョンのAMIにそれぞれ置き換えてください。

Description: Create EC2 Instance
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', hvm]
#FindInMap関数でMappings関数からのものを指定する。
      InstanceType: !Ref InstanceType
      Tags:
      - Key: Name
        Value: ec2
```

#4.サブネットを指定する#

```json
AWSTemplateFormatVersion: "2010-09-09"
Description: Create EC2 Instance
Parameters:
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
    - t1.micro
    - t2.nano
    - t2.micro
    - t2.small
    - t2.medium
    - t2.large
    ConstraintDescription: must be a valid EC2 instance type
  SubnetId:
    Type: String
    Default: subnet-0a17e4a1945a371a8
    AllowedValues:
    - subnet-0a17e4a1945a371a8
    - subnet-08a5374d316da6f60
    - subnet-0c7bd98f8caa00b15
    - subnet-09621152100bbd5f6
    ConstraintDescription: must be a valid SbunetID
#自分のサブネットIDを指定してください。

Mappings: 
  RegionMap: 
    ap-northeast-1:
      hvm: "ami-06a17900f024535fb"
    ap-southeast-1:
      hvm: "ami-055a628643638b600"


Description: Create EC2 Instance
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', hvm]
      InstanceType: !Ref InstanceType
      SubnetId: !Ref SubnetId
#Ref関数を指定します。
      Tags:
      - Key: Name
        Value: ec2
```

#5.ストーレージタイプを指定できるようにする#

```json
AWSTemplateFormatVersion: "2010-09-09"
Description: Create EC2 Instance
Parameters:
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
    - t1.micro
    - t2.nano
    - t2.micro
    - t2.small
    - t2.medium
    - t2.large
    ConstraintDescription: must be a valid EC2 instance type
  SubnetId:
    Type: String
    Default: subnet-0a17e4a1945a371a8
    AllowedValues:
    - subnet-0a17e4a1945a371a8
    - subnet-08a5374d316da6f60
    - subnet-0c7bd98f8caa00b15
    - subnet-09621152100bbd5f6
    ConstraintDescription: must be a valid SbunetID


Mappings: 
  RegionMap: 
    ap-northeast-1:
      hvm: "ami-06a17900f024535fb"
    ap-southeast-1:
      hvm: "ami-055a628643638b600"


Description: Create EC2 Instance
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', hvm]
      InstanceType: !Ref InstanceType
      SubnetId: !Ref SubnetId
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeType: gp2
            VolumeSize: 8
#ブロックデバイスを追加しています。もちろんParametersに設定して反映させることも可能です。
      Tags:
      - Key: Name
        Value: ec2
```

#6.セキュリティグループとSSHを選択できるようにする。#

```json
AWSTemplateFormatVersion: "2010-09-09"
Description: Create EC2 Instance
Parameters:
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
    - t1.micro
    - t2.nano
    - t2.micro
    - t2.small
    - t2.medium
    - t2.large
    ConstraintDescription: must be a valid EC2 instance type
  SubnetId:
    Type: String
    Default: subnet-0a17e4a1945a371a8
    AllowedValues:
    - subnet-0a17e4a1945a371a8
    - subnet-08a5374d316da6f60
    - subnet-0c7bd98f8caa00b15
    - subnet-09621152100bbd5f6
    ConstraintDescription: must be a valid SbunetID
  KeyName: 
    Description : Name of an existing EC2 KeyPair.
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription : Can contain only ASCII characters.
#KeyPairを指定する。
  SSHLocation:
    Description: IP address range that can be used to SSH to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    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.
#SSHを解放する値を指定する。

Mappings: 
  RegionMap: 
    ap-northeast-1:
      hvm: "ami-06a17900f024535fb"
    ap-southeast-1:
      hvm: "ami-055a628643638b600"

Description: Create EC2 Instance
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', hvm]
      InstanceType: !Ref InstanceType
      SubnetId: !Ref SubnetId
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeType: gp2
            VolumeSize: 8
      Tags:
      - Key: Name
        Value: myInstance
      KeyName: !Ref KeyName
#Parametersで指定したKeyNameを指定できるようにする。
      SecurityGroupIds:
         - !GetAtt "InstanceSecurityGroup.GroupId"
#セキュリティグループは別のリソースになります。ここでは下のInstanceSecurityGroupをSecurityGroupIdsに指定します。

  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: connect with ssh 
      VpcId: vpc-08fbdc5732395adab
#自分のVpcIdに変更してください。
      SecurityGroupIngress:
        -
          IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation
```

#7.VPCを構築してみる。#

```json
AWSTemplateFormatVersion: '2010-09-09'
Description:
  VPC & subnet create

Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      InstanceTenancy: default
      Tags:
      - Key: Name
        Value: CloudFormation-VPC
		
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
      - Key: Name
        Value: CloudFormation-VPC-PublicRT

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
      - Key: Name
        Value: CloudFormation-VPC-PrivateRT

  PublicSubnet1A:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: "ap-northeast-1a"
      Tags:
      - Key: Name
        Value: CloudFormation-public-subnet-1a

  PubSubnet1ARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1A
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet1C:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: "ap-northeast-1c"
      Tags:
      - Key: Name
        Value: CloudFormation-public-subnet-1c

  PubSubnet1CRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1C
      RouteTableId: !Ref PublicRouteTable

  PrivateSubnet1A:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: "ap-northeast-1a"
      Tags:
      - Key: Name
        Value: CloudFormation-private-subnet-1a

  PriSubnet1ARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1A
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnet1C:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: "ap-northeast-1c"
      Tags:
      - Key: Name
        Value: CloudFormation-private-subnet-1c

  PriSubnet1CRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1C
      RouteTableId: !Ref PrivateRouteTable

  myInternetGateway:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
      - Key: Name
        Value: CloudFormation-ING
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MyVPC
      InternetGatewayId: !Ref myInternetGateway
  myRoute:
    Type: AWS::EC2::Route
    DependsOn: myInternetGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref myInternetGateway

Outputs:
  StackVPC:
    Description: The ID of the VPC
    Value: !Ref MyVPC
    Export:
      Name: !Sub "${AWS::StackName}-VPCID"

  StackPublicSubnet1A:
    Description: The ID of the VPC Subnet
    Value: !Ref PublicSubnet1A
    Export:
      Name: !Sub "${AWS::StackName}-PublicSubnet1A"
![スクリーンショット 2019-05-25 21.34.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/c2177b63-b26a-f407-04d6-b169efd47f76.png)

  StackPublicSubnet1C:
    Description: The ID of the VPC Subnet
    Value: !Ref PublicSubnet1C
    Export:
      Name: !Sub "${AWS::StackName}-PublicSubnet1C"

  StackPrivateSubnet1A:
    Description: The ID of the VPC Subnet
    Value: !Ref PrivateSubnet1A
    Export:
      Name: !Sub "${AWS::StackName}-PrivateSubnet1A"

  StackPrivateSubnet1C:
    Description: The ID of the VPC Subnet
    Value: !Ref PrivateSubnet1C
    Export:
      Name: !Sub "${AWS::StackName}-PrivateSubnet1C"
```

Outputsで作成したものが以下のようにエクスポートに作成される。
![スクリーンショット 2019-05-25 21.34.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/a6373b18-e180-0aa5-27f2-e0ea0e41b9b3.png)

例えばEC2インスタンスを今作成したVPCのサブネットに作成したい場合、
EC2スタックの方に以下の通り記述することで、インポートすることができる。

`SubnetId: !ImportValue naata-PublicSubnet1A`

このようにいくつかのテンプレートを分けて運用する。