8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

何かと便利なCloudFormationを触ってみた

Last updated at Posted at 2022-12-23

目次

1. はじめに
2. 用語
3. やりたいこと
4. 作成するリソース
5. やってみた
6. まとめ
7. 参考

1. はじめに

こんにちは。
AWSの魅力の沼にハマり出したインフラエンジニアです!
最近、AWSの環境を複製する機会が何回かありました。
AWS環境が増える度に、環境構築をするのは正直めんどくさい。。。
そうだ!CloudFormationを利用しよう!
ということで、CloudFormationを触ってみました。

2. 用語

CloudFormationとは

CloudFormationはプログラミング言語やテキストファイルを使用してAWSリソースを自動で構築するサービスです。
所望のAWS環境をテンプレート化しておくことで、同じ環境を作成する時間を削減することができます。

スタックとは

スタックは、単一のユニットとして管理できる AWS リソースのコレクションです。
スタックを作成、更新、削除することで、リソースのコレクションを作成、更新、削除できます。
スタック内のすべてのリソースは、スタックの AWS CloudFormation テンプレートで定義されます。

3. やりたいこと

今回はCloudFormationを利用し、簡単な環境を作りEC2インスタンスを立ててみたいと思います。
AWSの構成図は、以下になります。(すごく簡単な構成で恐縮です。)
qiita用-環境構成図.png

4. 作成するリソース

  • VPC
  • サブネット(パブリックサブネット / プライベートサブネット)
  • EC2
  • インターネットゲートウェイ
  • セキュリティーグループ

5. やってみた

それでは、CloudFormationを利用してEC2インスタンスを作成していきたいと思います。

5-1. テンプレートを準備

テンプレート内では、作成するリソースの詳細設定を記述します。
ex) EC2インスタンスのインスタンス名、インスタンスタイプ、インスタンスのサイズ等

AWSTemplateFormatVersion: "2010-09-09"
Description:
  AWS-Environment-Template
  
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups: #各リソースのパラメータを管理
      - Label: #Labelでどのリソースのパラメータなのか区別
          default: "VPC Definition"
        Parameters:
          - VPCCIDR
          - DNSSupport
          - DNSHostNames
          - VPCName

      - Label:
          default: "InternetGateway Definition"
        Parameters:
          - IGWName

      - Label:
          default: "Subnet Definition"
        Parameters:
          - PublicSubnet1aName
          - PublicSubnet1aCIDRBlock
          - PrivateSubnet1aName
          - PrivateSubnet1aCIDRBlock
          - PublicSubnet1cName
          - PublicSubnet1cCIDRBlock
          - PrivateSubnet1cName
          - PrivateSubnet1cCIDRBlock

      - Label:
         default: "RouteTable Definition"
        Parameters:
          - PublicSubnetRouteTableName
          - PrivateSubnetRouteTableName

      - Label:
         default: "Define Security Group For EC2 Instance"
        Parameters:
          - EC2SecurityGroupName

      - Label:
         default: "EC2 Instance Definition"
        Parameters:
          - EC2InstanceName
          - EC2ImageId
          - EC2InstanceType
          - EC2KeyName

    ParameterLabels: #ParameterLabelsではParametersで定義したパラメータの説明を記載
      VPCCIDR:
        default: "VPC CIDR"
      DNSSupport: 
        default: "Whether DNS resolution is supported - true or false"
      DNSHostNames:
        default: "Whether to get the DNS host name - true or false"
      VPCName:
        default: "VPC Name"
      IGWName:
        default: "IGW Name"
      PublicSubnet1aName:
        default: "Public Subnet 1a Name"
      PublicSubnet1aCIDRBlock:
        default: "CIDR Block"
      PrivateSubnet1aName:
        default: "Private Subnet 1a Name"
      PrivateSubnet1aCIDRBlock:
        default: "CIDR Block"
      PublicSubnet1cName:
        default: "Public Subnet 1c Name"
      PublicSubnet1cCIDRBlock:
        default: "CIDR Block"
      PrivateSubnet1cName:
        default: "Private Subnet 1c Name"
      PrivateSubnet1cCIDRBlock:
        default: "CIDR Block"
      PublicSubnetRouteTableName:
        default: "Public Subnet  RouteTable Name"
      PrivateSubnetRouteTableName:
        default: "Private Subnet RouteTable Name"
      EC2SecurityGroupName:
        default: "Security Group Name For Instance"
      EC2InstaNcename:
        default: "Instance Name"
      EC2ImageId:
        default: "ami-09038cccc3722883e"
      EC2InstanceType:
        default: "Instance Type"
      EC2KeyName:
        default: "Key Name"
      
Parameters: #各パラメータの値を定義
  VPCCIDR:
    Type: String
    Default: "10.0.1.0/24"
    
  DNSSupport:
    Type: String
    Default: "true"
    
  DNSHostNames:
    Type: String
    Default: "true"
  
  VPCName:
    Type: String
    Default: "environment-name-vpc"

  IGWName:
    Type: String
    Default: "environment-name-igw"
    
  PublicSubnet1aName:
    Type: String
    Default: "environment-name-public-subnet-1a"

  PublicSubnet1aCIDRBlock:
    Type: String
    Default: "10.0.1.0/26"

  PrivateSubnet1aName:
    Type: String
    Default: "environment-name-private-subnet-1a"

  PrivateSubnet1aCIDRBlock:
    Type: String
    Default: "10.0.1.64/26"

  PublicSubnet1cName:
    Type: String
    Default: "environment-name-public-subnet-1c"
  
  PublicSubnet1cCIDRBlock:
    Type: String
    Default: "10.0.1.128/26"

  PrivateSubnet1cName:
    Type: String
    Default: "environment-name-private-subnet-1c"

  PrivateSubnet1cCIDRBlock:
    Type: String
    Default: "10.0.1.192/26"
  
  PublicSubnetRouteTableName:
    Type: String
    Default: "environment-name-public-rtb"

  PrivateSubnetRouteTableName:
    Type: String
    Default: "environment-name-private-rtb"

  EC2SecurityGroupName:
    Type: String
    Default: "environment-name-sg"

  EC2InstanceName:
    Type: String
    Default: "environment-name-az"
  
  EC2ImageId:
    Type: String
    Default: "ami-072bfb8ae2c884cc4"
  
  EC2InstanceType:
    Type: String
    Default: "t2.micro"

  EC2KeyName:
    Type: String
    Default: "test-key"

Resources: #Resourcesでは各リソースの詳細設定を定義

  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VPCCIDR
      EnableDnsSupport: !Ref DNSSupport
      EnableDnsHostnames: !Ref DNSHostNames
      Tags:
        - Key: Name
          Value: !Ref VPCName
 
  IGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Ref IGWName
  
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref IGW
      VpcId: !Ref VPC
 
  PublicSubnet1a:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: !Ref PublicSubnet1aCIDRBlock
      Tags:
        - Key: Name
          Value: !Ref PublicSubnet1aName

  PrivateSubnet1a:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: !Ref PrivateSubnet1aCIDRBlock
      Tags:
        - Key: Name
          Value: !Ref PrivateSubnet1aName

  PublicSubnet1c:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: "ap-northeast-1c"
      CidrBlock: !Ref PublicSubnet1cCIDRBlock
      Tags:
        - Key: Name
          Value: !Ref PublicSubnet1cName

  PrivateSubnet1c:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: "ap-northeast-1c"
      CidrBlock: !Ref PrivateSubnet1cCIDRBlock
      Tags:
        - Key: Name
          Value: !Ref PrivateSubnet1cName

  PublicSubnetRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Ref PublicSubnetRouteTableName

  PrivateSubnetRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Ref PrivateSubnetRouteTableName

  PublicSubnetRouteSetting:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicSubnetRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref IGW

  AttachPublicSubnetRouteTable1a:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicSubnetRouteTable
      SubnetId: !Ref PublicSubnet1a

  AttachPublicSubnetRouteTable1c:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicSubnetRouteTable
      SubnetId: !Ref PublicSubnet1c

  AttachPrivateSubnetRouteTable1a:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateSubnetRouteTable
      SubnetId: !Ref PrivateSubnet1a

  AttachPrivateSubnetRouteTable1c:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateSubnetRouteTable
      SubnetId: !Ref PrivateSubnet1c
  
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPC
      GroupDescription: "My-NetWork"
      SecurityGroupIngress:
        - IpProtocol: -1
          CidrIp: 10.100.0.0/16
      Tags:
        - Key: Name
          Value: !Ref EC2SecurityGroupName

  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2ImageId
      InstanceType: !Ref EC2InstanceType
      KeyName: !Ref EC2KeyName
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          GroupSet: 
            - Ref: "InstanceSecurityGroup"
          SubnetId: !Ref PublicSubnet1a
      Tags:
        - Key: Name
          Value: !Ref EC2InstanceName

ParameterGroupとは

パラメータをまとめて定義することができます。
ParameterGroup内でさらに分類したい場合は、Labelを使用することで分類できます。

Parametersセクションとは

パラメータを使用すると、スタックを作成または更新する度にテンプレートにカスタム値を入力できます。

5-2. スタックを作成

CloudFormation Management Consoleから「スタック」➡「スタックの作成」をクリック。
テンプレートの準備では、「テンプレートの準備完了」を選択し、「テンプレートファイルのアップロード」を選択します。
上記を選択することで、テンプレートファイルをアップロードすることが可能になります。
(テンプレートは上記を使用しました。)
qiita用-スタックの作成1.png

次に、スタックの詳細設定を行います。
今回スタックの名前は、「test-stack」としました。
パラメータは、状況にあった値に変更してください。
今回は、デフォルトの値で作成しました。
qiita用-スタック作成2.png
上記のパラメータのセクションで、テンプレートで定義したパラメータが表示されていることがわかります。
また、VPC / インターネットゲートウェイのように、Labelで区切ったリソースごとにパラメータが表示されていることもわかります。
qiita用-スタック作成3.png
パラメータのセクションで入力されている値は、テンプレートのParametersのDefaultに設定した値が表示されます。
qiita用-スタック作成4.png
スタックオプションでは、任意でタグを追加してください。
アクセス許可では、デフォルトのままで設定します。
スタックの失敗オプションでは、「すべてのスタックリソースをロールバックする」を選択します。
qiita用-スタック作成5.png
以下は、すべてデフォルトのままでOK。
qiita用-スタック作成6.png
最後にレビューとなります。
上記で設定したパラメータが確認できます。
設定に問題がなければ、「送信」をクリックします。
qiita用-スタック7.png
qiita用-スタック8.png
送信されると、CoudFormationのスタックが実行され、テンプレートで設定したリソースが作成されます。

5-2. 作成したリソースを確認

スタックの実行が正常に完了した場合、「CREATE_COMPLETE」が表示されます。
スタック状況.png
また、イベントでは作成したリソースの状況を細かく確認することができます。スタックイベント1.png
実際に作成されたリソースも確認してみます。
インスタンスの状態.png
テンプレートで指定したVPC / サブネット / EC2が作成されていることがわかります。

6. まとめ

CloudFormationでリソースの一元管理をすることで、管理者の作業負担と時間短縮に貢献できる。
CloudFormationで作成したリソースすべてを削除したい場合は、対応するスタックを削除することで可能。
(残しておきたいリソースを選択することで、削除しないことも可能。)
今回は簡単な構築をCloudFormationで作成しましたが、次回はより複雑な構築を行いたいと思います。
皆さんもとても便利なCloudFormationを活用して、作業負担と時間短縮をしていきましょう!!!

7. 参考

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?