2
0

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.

概要

ServerlessFrameworkを利用する中で、内部的にCloudFormationを利用していたので改めて調べてみたり、自分なりに「ここめっちゃいい!」と思ったところをまとめました
触り部分が多いので初心者向けの記事ですが読んでもらえればと思います :pray:

CloufFormationって

CloudFormationで利用するテンプレート(JSONもしくはYAML)にAWSリソースを記述することでテンプレートにしたがってリソースの作成・更新削除といった管理ができるサービスです

たとえばEC2を作成して、Apacheサーバーを建てて、ユーザーからもアクセスできるように...といった内容をAWSコンソールを利用せずにCloudFormationテンプレートを作成し、そのテンプレートファイルをデプロイすることで実行できます

個人的に感じるメリット

これはCloudFormationに限った話ではありませんが、CloudFormationはIaC(Infrastructure as Code)なのでそれらで述べられている特徴を持っています

特筆して感じるメリットとしては
インフラ変更差分に対してメッセージを残しやすい」ことです

具体的な仕事の例を上げると
前提: EC2を利用してWebアプリケーションを管理している
一般ユーザーからも閲覧できる本番環境と
本番環境と同じ構成で社内アクセスのみを許可したステージング環境が存在する
対応依頼: 新しく入った開発パートナーさんにもステージング環境にアクセスできるようにしたい
対応方針: セキュリティグループに許可するIPアドレスを追加する

CloudFormationならコード管理できるため、Gitなどのバージョン管理でコメントや変更意図を含めて管理できます
そのため数年後に「このIPアドレスって誰が使っているものなのか」と発見したときにgit logなどから追跡が可能です

また再現性が持てるところも素晴らしいです
大量のユーザーアクセスを捌けるようなAPIGateway + SQS + LambdaといったようなServerless構成を自分がCloudFormationを利用して作成しました
友人にも同様のシステムを提供しようと思ったときにCloudFormationのテンプレートを共有するだけで各々のアカウントで同一のAWS構成が作られます

この再現性の部分をAWSコンソールで行おうとしたときに1つのミスもなく、まったく同一の構成にするのはとても難しいです
これはメモを用いずに居酒屋の10人席へ注文を伺い1つの誤りもなく注文を聞き取り、伝えるくらい難易度が高いです

また各種CloudFormationのテンプレートを利用してデプロイする単位はスタックといいます
(スタックは複数のAWSリソースを管理する単位のようなものと認識するほうが考えやすい)

どうやって使うのか

このスタックを作成する方法は大きく3つあります

  1. CloudFormationのテンプレートを自分で作成する
  2. サンプルテンプレートを利用する
  3. CloudFormationのデザイナーを利用してGUIで構成を作成する

個人的には1の自身でテンプレートを作成することが多いかと思います

スクリーンショット 2023-12-04 23.34.19.png

実際に書いてみる

今回はサンプルとしてEC2上にapacheサーバーを建てて自分のパソコンからアクセスできるようにしてみましょう

下記のようなテンプレートを定義します
行っていることとしては

  • Resourcesセクション内でAWSのリソースを作成している
    • MyVPC
      MySubnet
      MyInternetGatewayなど...
  • 各種リソース名配下では[リソースタイプ名][リソースのプロパティ]を定義
    • リソースタイプ名はドキュメントにすべて書いてある
    • またリソースのプロパティはリソースごとに異なるのでこちらもドキュメントを見るのが一番良い
  • Outputsセクション内でスタックが出力する項目について出力している
    • 今回は MyVPCのvpcid MySubnetのsubnetIdを出力
  • !Refと記載することで同じテンプレート内で定義している他のリソースを参照
    • VpcId: !Ref MyVPCとすることでMyVPCのvpcIdに置き換わる
    • Ex) VpcId: !Ref MyVPCVpcId: vpc-xxxxxxxx
vpc-template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template to deploy an Apache server with a VPC.

Resources:
  MyVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: MyVPC

  MySubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.1.0/24
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: MySubnet

  MyInternetGateway:
    Type: 'AWS::EC2::InternetGateway'

  GatewayAttachment:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref MyVPC
      InternetGatewayId: !Ref MyInternetGateway

  MyRouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref MyVPC

  MyRoute:
    Type: 'AWS::EC2::Route'
    Properties:
      RouteTableId: !Ref MyRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref MyInternetGateway

  SubnetRouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref MySubnet
      RouteTableId: !Ref MyRouteTable
Outputs:
  VPCId:
    Description: The ID of the VPC
    Value: !Ref MyVPC
  SubnetId:
    Description: The ID of the subnet
    Value: !Ref MySubnet

実際にデプロイしてみる

# create-stack で template-bodyにあるファイルを元にCloudFormationでスタックを作成
$ aws cloudformation create-stack --stack-name VPCStack --template-body file://vpc-template.yaml

AWSコンソール上ではどのリソースがどんなステータスでどういう状況となっているかが確認できます
create-stackが成功するとスタックのステータスがCREATE_COMPLEATEになり、コンソール上もしくはdescribe-stacksの実行結果で確認できます

スクリーンショット 2023-12-04 23.56.16.png

続いてEC2のデプロイを行いますがVPCのIDとSubnetのIDがほしいのでメモしておきます
describe-stacksを実行してOutputsするように設定した各種IDを控えておきます
VPCIdはvpc-AAAAAAAAASubnetIdはsubnet-BBBBBBBだとわかります

$ aws cloudformation describe-stacks --stack-name VPCStack
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXX:stack/VPCStack/XXXX-YYY3-XXXX-XXXX-ZZZZZ",
            "StackName": "VPCStack",
            "Description": "CloudFormation template to deploy an Apache server with a VPC.",
            "CreationTime": "2023-12-04T14:41:46.862000+00:00",
            "RollbackConfiguration": {},
            "StackStatus": "CREATE_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Outputs": [
                {
                    "OutputKey": "VPCId",
                    "OutputValue": "vpc-AAAAAAAAA",
                    "Description": "The ID of the VPC"
                },
                {
                    "OutputKey": "SubnetId",
                    "OutputValue": "subnet-BBBBBBB",
                    "Description": "The ID of the subnet"
                }
            ].....

続いてApache用のCloudformationのテンプレートファイルを作成します
VPCのテンプレートと異なる点としてはParametersセクションが追加されています

これはコマンド実行時のオプションに値を渡せます
今回はVPCIdとしているので --parameters ParameterKey=VPCId,ParameterValue=vpc-AAAAAAAAAとすることで!Refで参照できます

apache-server-template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template to deploy an Apache server with restricted access.

Parameters:
  VPCId:
    Description: The ID of the VPC
    Type: String

  SubnetId:
    Description: The ID of the subnet
    Type: String

  AllowedIPAddress:
    Description: IP address allowed to access the Apache server.
    Type: String

Resources:
  MyInstance:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: ami-012261b9035f8f938
      InstanceType: t2.micro
      SubnetId: !Ref SubnetId
      SecurityGroupIds:
        - Ref: InstanceSecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "<html><body><h1>Welcome to Apache Server</h1></body></html>" > /var/www/html/index.html

  InstanceSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: Enable SSH and HTTP access on the configured port
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref AllowedIPAddress
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref AllowedIPAddress
      VpcId: !Ref VPCId

実際にデプロイしてみましょう

aws cloudformation create-stack \
  --stack-name ApacheServerStack \
  --template-body file://apache-server-template.yaml \
  --parameters ParameterKey=VPCId,ParameterValue=vpc-AAAAAAAAA \
                ParameterKey=SubnetId,ParameterValue=subnet-BBBBBBB \
                ParameterKey=AllowedIPAddress,ParameterValue=127.0.0.1/32 # ここだけ自分のIPアドレスに変更する

デプロイが完了したらブラウザからEC2にアクセスするかcurlなどを叩いて確認しましょう

スクリーンショット 2023-12-05 0.14.05.png

またCloudFormationのテンプレートを変更した場合はupdate-stack, スタックで管理していたリソースが不要になったらdelete-stacksを実行して適宜削除しましょう

終わり

ServerlessFramework経由でCloudFormationを利用することはありましたが、改めて確認してみました

各種templateはサンプルコードとして↓のリポジトリに載せています

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?