1. CloudFormationテンプレートパーツ (create: template)

作業の目的 [why]

CloudFormationテンプレート"20171225-handson"のリソース定義を作成します。

完了条件/事前条件 [設計者用情報]

完了条件 [after]

主処理は、以下を満たしたときに成功したものとします。

完了条件1
作成したファイルが存在する。

事前条件 [before]

主処理の実施は、以下の状態であることを前提とします。

事前条件1
作業用ディレクトリが存在する。

前提と異なることが判明した場合、直ちに処理を中止します。

課題

(未検証)

作業対象 [what]

  • ローカル環境

標準時間

8分

前提条件

作業権限条件 [who]

本作業は、以下の作業権限を有する人が行います。

作業権限条件: 特になし

(特になし)

作業環境条件 [where]

本作業は、以下の作業環境で行います。

作業環境条件1: OSとバージョン

Amazon Linuxの以下のバージョンで動作確認済

コマンド:

cat /etc/issue | head -1

結果(例):

Amazon Linux AMI release 2016.09

作業環境条件2: シェルとバージョン

bashの以下のバージョンで動作確認済

コマンド:

bash --version -v | head -1

結果(例):

GNU bash, バージョン 4.2.46(1)-release (x86_64-redhat-linux-gnu)

開始条件

作業に必要なモノ・情報 [resource]

作業開始には、以下が全て揃っていることが必要です。

リソース1: CloudFormationテンプレート名

  • 作成するCloudFormationテンプレートの名称です。
  • 今回は"20171225-handson"とします。

リソース2: 作業用ディレクトリ

  • 今回は"${HOME}/tmp/cfn-20171225-handson"を作業用ディレクトリとします。

    ls ${HOME}/tmp/cfn-20171225-handson
    
  • 存在しない場合は作成します。

    mkdir -p ${HOME}/tmp/cfn-20171225-handson
    

リソース3: VPC名

  • 作成するVPCの名称です。
  • 今回は"VpcHandson20171225"とします。

リソース4: VPCで利用するCIDR

  • 作成するVPCが利用するCIDRです。
  • 今回は"192.168.192.0/16"とします。

リソース5: IGW名

  • 作成するIGWの名称です。
  • 今回は"IgwHandson20171225"とします。

リソース6: GWアタッチ名

  • 作成するIGWのGWアタッチ名称です。
  • 今回は"GWAttachment0"とします。

リソース7: ルートテーブル名

  • 作成するルートテーブルの名称です。
  • 今回は"RouteTableHandson20171225"とします。

リソース8: ルート先のCIDR

  • 作成するルートのルート先CIDRです。
  • 今回は"0.0.0.0/0"とします。

リソース9: ルート名

  • 作成するルートの名称です。
  • 今回は"RouteIgwHandson20171225"とします。

リソース10: AZ名

  • サブネットを作成するAZ名です。
  • 今回は"ap-northeast-1a"とします。

リソース11: サブネットのCIDR

  • 作成するサブネットのCIDRです。
  • 今回は"192.168.192.0/24"とします。

リソース12: サブネット名

  • 作成するサブネットの名称です。
  • 今回は"Subnet01Handson20171225"とします。

リソース13: サブネットのPublic有効/無効

  • 作成するサブネットで起動するインスタンスがデフォルトでPublicアドレスを付与されるかどうかの設定です。
  • 今回は"True"とします。

リソース14: サブネットとルートテーブルの紐付け名

  • サブネットとルートテーブルの紐付け名称です。
  • 今回は"Subnet01RoutetableAssocHandson20171225"とします。

リソース15: セキュリティグループ名

  • 作成するセキュリティグループの名称です。
  • 今回は"SshPublic"とします。

リソース16: セキュリティグループの説明

  • 作成するセキュリティグループの説明です。
  • 今回は"ssh public"とします。

リソース17: セキュリティグループの対象のプロトコル

  • 作成するセキュリティグループの対象のプロトコル名称です。
  • 今回は"tcp"とします。

リソース18: セキュリティグループの対象のポート番号

  • 作成するセキュリティグループの対象のポート番号名称です。
  • 今回は"22"とします。

リソース19: セキュリティグループの対象のCIDR

  • 作成するセキュリティグループの対象のCIDRです。
  • 今回は"0.0.0.0/0"とします。

リソース20: EC2イメージのID

  • 作成する名称です。
  • 今回は"<イメージID>"とします。

作業開始 [when]

以下を全て満たしているとき、作業を開始します。

  • 開始の指示があった場合。

タスクの実施

0. パラメータの指定

まず変数の確認をします。

変数の確認:

cat << ETX

  # 0.1. DIR_TMP:"${HOME}/tmp/cfn-20171225-handson"
         DIR_TMP="${DIR_TMP}"
  # 0.2. CFN_TEMPLATE_NAME:"20171225-handson"
         CFN_TEMPLATE_NAME="${CFN_TEMPLATE_NAME}"
  # 0.3. VPC_NAME:"VpcHandson20171225"
         VPC_NAME="${VPC_NAME}"
  # 0.4. VPC_CIDR:"192.168.192.0/16"
         VPC_CIDR="${VPC_CIDR}"
  # 0.5. VPC_IGW_NAME:"IgwHandson20171225"
         VPC_IGW_NAME="${VPC_IGW_NAME}"
  # 0.6. VPC_GW_ATTACHMENT_NAME:"GWAttachment0"
         VPC_GW_ATTACHMENT_NAME="${VPC_GW_ATTACHMENT_NAME}"

ETX

下段の変数が入っていない、もしくは上段と同等の値が入っていない場合は、それぞれの手順番号について作業を行います。

0.1. 作業用ディレクトリの指定

変数の設定:

DIR_TMP="${HOME}/tmp/cfn-20171225-handson"

0.2. CloudFormationテンプレート名の指定

CloudFormationテンプレート名を指定します。

変数の設定:

CFN_TEMPLATE_NAME='20171225-handson'

0.3. VPC名の指定

VPCの名称を指定します。

変数の設定:

VPC_NAME='VpcHandson20171225'

0.4. VPCのCIDR指定

VPCのCIDRを指定します。

変数の設定:

VPC_CIDR='192.168.192.0/16'

0.5. IGW名の指定

IGWの名称を指定します。

変数の設定:

VPC_IGW_NAME='IgwHandson20171225'

0.6. GWアタッチ名の指定

GWアタッチの名称を指定します。

変数の設定:

VPC_GW_ATTACHMENT_NAME='GWAttachment0'

変数の設定:

CFN_TEMPLATE_NAME="20171225-handson"

VPC_NAME="VpcHandson20171225"

VPC_CIDR="192.168.192.0/16"

VPC_IGW_NAME="IgwHandson20171225"

VPC_GW_ATTACHMENT_NAME="GWAttachment0"

VPC_ROUTETABLE_NAME="RouteTableHandson20171225"

VPC_ROUTE_DEST_CIDR="0.0.0.0/0"

VPC_ROUTE_NAME="RouteIgwHandson20171225"

VPC_AZ_NAME="ap-northeast-1a"

VPC_SUBNET_CIDR="192.168.192.0/24"

VPC_SUBNET_NAME="Subnet01Handson20171225"

VPC_SUBNET_PUBLIC="True"

VPC_SUBNET_ROUTETABLE_ASSOC_NAME="Subnet01RoutetableAssocHandson20171225"

VPC_SG_NAME="SshPublic"

VPC_SG_DESC="ssh public"

VPC_SG_PROTOCOL="tcp"

VPC_SG_PORT="22"

VPC_SG_CIDR="0.0.0.0/0"

再確認

設定されている変数の内容を再確認します。

1. 前処理

1.1. 処理対象の状態確認

主処理の実施は、以下の状態であることを前提とします。

前提と異なることが判明した場合、直ちに処理を中止します。

事前条件1: 作業用ディレクトリが存在する。

「作業用ディレクトリが存在する。」ことを確認します。

コマンド:

ls -d ${DIR_TMP}

結果(例):

${HOME}/tmp/cfn-20171225-handson

1.2. 主処理に必要な情報の取得

作業用ディレクトリの作成

${HOME}/tmp/cfn-20171225-handson/resourcesディレクトリが存在することを確認します。

コマンド:

ls -d ${DIR_TMP}/resources

存在しない場合は、ディレクトリを作成します。

コマンド:

mkdir -p ${DIR_TMP}/resources

2. 主処理 (Resourceの作成)

1. VPCの作成

変数の確認:

cat << ETX

  #VPC_NAME:"VpcHandson20171225"
   VPC_NAME="${VPC_NAME}"
  #VPC_CIDR:"192.168.192.0/16"
   VPC_CIDR="${VPC_CIDR}"

ETX

コマンド:

cat << EOF > ${DIR_TMP}/resources/AWS_EC2_VPC-${VPC_NAME}.txt
  ${VPC_NAME}:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: ${VPC_CIDR}
      Tags:
        - Key: Name
          Value: ${VPC_NAME}

EOF

cat ${DIR_TMP}/resources/AWS_EC2_VPC-${VPC_NAME}.txt

結果(例):

VpcHandson20171225:
  Type: AWS::EC2::VPC
  Properties:
    CidrBlock: 192.168.192.0/16
    Tags:
      - Key: Name
        Value: VpcHandson20171225

2. InternetGatewayの作成

変数の確認:

cat << ETX

  #VPC_IGW_NAME:"IgwHandson20171225"
   VPC_IGW_NAME="${VPC_IGW_NAME}"

ETX

コマンド:

cat << EOF > ${DIR_TMP}/resources/AWS_EC2_InternetGateway-${VPC_IGW_NAME}.txt
  ${VPC_IGW_NAME}:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: ${VPC_IGW_NAME}

EOF

cat ${DIR_TMP}/resources/AWS_EC2_InternetGateway-${VPC_IGW_NAME}.txt

結果(例):

IgwHandson20171225:
  Type: AWS::EC2::InternetGateway
  Properties:
    Tags:
      - Key: Name
        Value: IgwHandson20171225

VPCGatewayAttachmentの作成

変数の確認:

cat << ETX

  #VPC_GW_ATTACHMENT_NAME:"GWAttachment0"
   VPC_GW_ATTACHMENT_NAME="${VPC_GW_ATTACHMENT_NAME}"
  #VPC_NAME:"VpcHandson20171225"
   VPC_NAME="${VPC_NAME}"
  #VPC_IGW_NAME "IgwHandson20171225"
   VPC_IGW_NAME="${VPC_IGW_NAME}"

ETX

コマンド:

cat << EOF > ${DIR_TMP}/resources/AWS_EC2_VPCGatewayAttachment-${VPC_GW_ATTACHMENT_NAME}.txt
  ${VPC_GW_ATTACHMENT_NAME}:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref ${VPC_IGW_NAME}
      VpcId: !Ref ${VPC_NAME}

EOF

cat ${DIR_TMP}/resources/AWS_EC2_VPCGatewayAttachment-${VPC_GW_ATTACHMENT_NAME}.txt

結果(例):

GWAttachment0:
  Type: AWS::EC2::VPCGatewayAttachment
  Properties:
    InternetGatewayId: IgwHandson20171225
    VpcId: VpcHandson20171225

ルートテーブルの作成

http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html

変数の確認:

cat << ETX

  # VPC_NAME:"VpcHandson20171225"
  VPC_NAME="${VPC_NAME}"
  # VPC_ROUTETABLE_NAME:"RouteTableHandson20171225"
  VPC_ROUTETABLE_NAME="${VPC_ROUTETABLE_NAME}"

ETX

コマンド:

cat << EOF > ${DIR_TMP}/resources/AWS_EC2_RouteTable-${VPC_ROUTETABLE_NAME}.txt
  ${VPC_ROUTETABLE_NAME}:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref ${VPC_NAME}
      Tags:
        - Key: Name
          Value: ${VPC_ROUTETABLE_NAME}
EOF

cat ${DIR_TMP}/resources/AWS_EC2_RouteTable-${VPC_ROUTETABLE_NAME}.txt

結果(例):

Subnet01Handson20171225:
  Type: "AWS::EC2::RouteTable"
  Properties:
    VpcId: !Ref VpcHandson20171225
    Tags:
      - Key: Name
        Value: RouteTableHandson20171225

ルートの追加

http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html

変数の確認:

cat << ETX

  # VPC_IGW_NAME:"IgwHandson20171225"
    VPC_IGW_NAME="${VPC_IGW_NAME}"
  # VPC_ROUTE_DEST_CIDR:"0.0.0.0/0"
    VPC_ROUTE_DEST_CIDR="${VPC_ROUTE_DEST_CIDR}"
  # VPC_ROUTE_NAME:"RouteIgwHandson20171225"
    VPC_ROUTE_NAME="${VPC_ROUTE_NAME}"
  # VPC_ROUTETABLE_NAME:"RouteTableHandson20171225"
    VPC_ROUTETABLE_NAME="${VPC_ROUTETABLE_NAME}"

ETX

コマンド:

cat << EOF > ${DIR_TMP}/resources/AWS_EC2_Route-${VPC_ROUTE_NAME}.txt
  ${VPC_ROUTE_NAME}:
    Type: "AWS::EC2::Route"
    Properties:
      DestinationCidrBlock: ${VPC_ROUTE_DEST_CIDR}
      GatewayId: !Ref ${VPC_IGW_NAME}
      RouteTableId: !Ref ${VPC_ROUTETABLE_NAME}

EOF

cat ${DIR_TMP}/resources/AWS_EC2_Route-${VPC_ROUTE_NAME}.txt

結果(例):

Subnet01Handson20171225:
  Type: "AWS::EC2::Route"
  Properties:
    DestinationCidrBlock: 0.0.0.0/0
    GatewayId: !Ref IgwHandson20171225
    RouteTableId: !Ref RouteTableHandson20171225

サブネットの作成

http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html

変数の確認:

cat << ETX

  # VPC_AZ_NAME:"ap-northeast-1a"
    VPC_AZ_NAME="${VPC_AZ_NAME}"
  # VPC_SUBNET_CIDR:"192.168.192.0/24"
    VPC_SUBNET_CIDR="${VPC_SUBNET_CIDR}"
  # VPC_SUBNET_NAME:"Subnet01Handson20171225"
    VPC_SUBNET_NAME="${VPC_SUBNET_NAME}"
  # VPC_SUBNET_PUBLIC:"True"
    VPC_SUBNET_PUBLIC="${VPC_SUBNET_PUBLIC}"
  # VPC_NAME:"VpcHandson20171225"
    VPC_NAME="${VPC_NAME}"

ETX

コマンド:

cat << EOF > ${DIR_TMP}/resources/AWS_EC2_Subnet-${VPC_SUBNET_NAME}.txt
  ${VPC_SUBNET_NAME}:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone: ${VPC_AZ_NAME}
      CidrBlock: ${VPC_SUBNET_CIDR}
      MapPublicIpOnLaunch: ${VPC_SUBNET_PUBLIC}
      Tags:
        - Key: Name
          Value: ${VPC_SUBNET_NAME}
      VpcId: !Ref ${VPC_NAME}

EOF

cat ${DIR_TMP}/resources/AWS_EC2_Subnet-${VPC_SUBNET_NAME}.txt

結果(例):

Subnet01Handson20171225:
  Type: "AWS::EC2::Subnet"
  Properties:
    AvailabilityZone: ap-northeast-1a
    CidrBlock: 192.168.192.0/24
    MapPublicIpOnLaunch: True
    Tags:
      - Key: Name
        Value: Subnet01Handson20171225
    VpcId: !Ref VpcHandson20171225

ルートテーブルの紐付け (Destination CIDR)

http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html

変数の確認:

cat << ETX

  # VPC_SUBNET_ROUTETABLE_ASSOC_NAME:"Subnet01RoutetableAssocHandson20171225"
    VPC_SUBNET_ROUTETABLE_ASSOC_NAME="${VPC_SUBNET_ROUTETABLE_ASSOC_NAME}
  # VPC_ROUTETABLE_NAME:"RouteTableHandson20171225"
    VPC_ROUTETABLE_NAME="${VPC_ROUTETABLE_NAME}
  # VPC_SUBNET_NAME:"Subnet01Handson20171225"
    VPC_SUBNET_NAME="${VPC_SUBNET_NAME}

ETX

コマンド:

cat << EOF > ${DIR_TMP}/resources/AWS_EC2_SubnetRouteTableAssociation-${VPC_SUBNET_ROUTETABLE_ASSOC_NAME}.txt
  ${VPC_SUBNET_ROUTETABLE_ASSOC_NAME}:
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties:
      RouteTableId: !Ref ${VPC_ROUTETABLE_NAME}
      SubnetId: !Ref ${VPC_SUBNET_NAME}

EOF

cat ${DIR_TMP}/resources/AWS_EC2_SubnetRouteTableAssociation-${VPC_SUBNET_ROUTETABLE_ASSOC_NAME}.txt

結果(例):

Subnet01Handson20171225:
  Type: "AWS::EC2::SubnetRouteTableAssociation"
  Properties:
    RouteTableId: !Ref RouteTableHandson20171225
    SubnetId: !Ref Subnet01Handson20171225

セキュリティグループ (SSH許可)

http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html

変数の確認:

cat << ETX

  #YET "|yet|"
   YET="${YET}"

ETX

コマンド:

cat << EOF > ${DIR_TMP}/resources/AWS_EC2_SecurityGroup-${VPC_SG_NAME}.txt
  ${VPC_SG_NAME}:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      GroupDescription: ${VPC_SG_DESC}
      VpcId: !Ref ${VPC_NAME}
      SecurityGroupIngress:
      - IpProtocol: ${VPC_SG_PROTOCOL}
        FromPort: '${VPC_SG_PORT}'
        ToPort: '${VPC_SG_PORT}'
        CidrIp: ${VPC_SG_CIDR}
      SecurityGroupEgress:
      - IpProtocol: -1
        CidrIp: ${VPC_SG_CIDR}

EOF

cat ${DIR_TMP}/resources/AWS_EC2_SecurityGroup-${VPC_SG_NAME}.txt

結果(例):

Subnet01Handson20171225:
  Type: "AWS::EC2::SecurityGroup"
  Properties:
    GroupDescription: ssh public
    VpcId: !Ref VpcHandson20171225
    SecurityGroupIngress:
    - IpProtocol: tcp
      FromPort: '22'
      ToPort: '22'
      CidrIp: 0.0.0.0/0
    SecurityGroupEgress:
    - IpProtocol: -1
      CidrIp: 0.0.0.0/0

3. 後処理

完了条件の確認

完了