EC2 Amazon Linux 2023使用 CloudFormation の導入についての備忘録|基礎インフラ【2】

パソコン

皆さんこんにちは、小幡です。

この記事は、基礎インフラ備忘録シリーズの第2回目です。1回目は以下のリンクから参照ください。

前回は、EC2インスタンスの起動をAWSマネジメントコンソールから行い、Nginx, Gunicorn, Djangoの導入をローカルPCからのSSH接続でインスタンスにアクセスした先でコマンドを実行していました。

これらの方法は、1つずつ機能や役割、実際に出来上がっている姿を目視で確認しながら理解を深めるためには有効な手法だと思います。もちろん本番環境の構築においても同じように実施することも可能です。

実際に私の経験してきた現場でもAWSマネジメントコンソールにアクセスしてクリックしながら、何かを操作するということは良くありました。AWSのいい所は簡単にリリース環境や個人検証環境を作成できることです。これからも検証環境のAWSマネジメントコンソールにアクセスをして、何かをクリックすることはあるはずですので、そういう意味でもGUIにも慣れておくことは非常に重要な事だと感じています。

さて、今回は上記の体験を踏まえた上で、これまで手動で行っていた作業を自動で行えるように、CloudFormationの導入と動作確認を行ったことについて備忘録として残したいと思います。

自分自身への備忘録的な記事なので、検証を行っていないところや、間違いもあると思いますのでご注意ください。

CloudFormation

CloudFormationとは、これまで行ってきたインフラの構築をコードで自動化や管理できるようにするためのサービスです。

このようなコードで自動化や管理をすることを「Infrastructure as Code」(IaC)と呼び、他のサービスではTerraformが有名です。こちらはAWSだけではなく、他のクラウドサービスでも利用可能です。

今回はAWSサービスのみの利用ということと、Terraform独自の記述方法を学ぶ必要があり学習コストの観点からCloudFormationを選択しています。

ここからは余談ですが、私がエンジニアとして働かせて貰っているなかで、常々悩まされていた作業の一つが開発環境の構築です。ローカルPCにVSCodeを導入することなどにおいても、インストールする方法が違ったり、オプションの設定が微妙に開発者によって異なっており、うまく起動出来なかったり、テスト実行がうまく行かなったりすることがよくあります。

なぜそのような不具合が発生するかと言えば、作業を人が行っているからです。

これと同様にテスト環境をAWS上で構築しようとした時も人はミスをします。結果、問題の調査と修正に時間が奪われてしまうのです。

さて、CloudFormationで使用する実際のテンプレートファイルについてみていきましょう

テンプレートファイル

自動化の管理をするために、コードとして書き出します。結果的には以下のようなyamlファイルとなります。

AWSTemplateFormatVersion: '2010-09-09'
Description: EC2 Instance for Django App Test

# 実行時にキーペア名を入力できるようにする
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
    Type: AWS::EC2::KeyPair::KeyName

Resources:
  # EC2インスタンスの定義
  MyDjangoServerTest:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-09cd9fdbf26acc6b4 # Amazon Linux 2023 (東京)
      InstanceType: t3.micro
      KeyName: !Ref KeyName
      SecurityGroupIds:
        - !Ref WebServerSecurityGroup
      Tags:
        - Key: Name
          Value: CFN-Django-Server

  # セキュリティグループ(ポート80と22を開ける)
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP and SSH access
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0 # 実際は自分のIPに制限するのが安全

このテンプレートファイルをCloudFormationで実行することができれば、EC2インスタンスとセキュリティグループを新しく作成し、SSH接続するときには、すでに作成済みのキーペアを使用することでアクセスできる状態になります。

Parameters

Parametersには、CloudFormationを実施する際にパラメータとして投入する値を設定できます。

今回の場合だと、KeyNameというパラメータを作成しており、EC2のキーペアを選択することになります。

Resources

Resourcesには、AWSのリソースを設定します。

今回の場合だと、MyDjangoServerTestという名前でEC2インスタンスの作成と、WebServerSecurityGroupという名前でセキュリティグループの作成をしています。

詳しい値については割愛しますが、この2つのリソースの設定がうまく噛み合うことで、AWSマネジメントコンソールで作成したように、それぞれが紐づいた状態で作成されることになります。

実行と動作確認

AWSマネジメントコンソールからCloudFormationの画面を開くと様々な実行方法が提示されます。

今回はローカルでテンプレートファイルを作成したので、このテンプレートファイルをアップロード、そして実行する流れです。

Parametersのところでも記載した通り、事前に作成しておいたキーペアを設定しないとエラーになります。

送信を実行するとスタックが作成され、作成中の表示になります。

まず、これが作成完了の状態にることを確認します。

この時、場合によっては失敗となることがありますが、焦らず実行結果を読み解き解決を地道に進めましょう。

失敗した場合は、デフォルトではロールバックする設定になっていると思いますが、一度スタックを削除してから、再度CloudFormationの実行をしましょう。すべて作成完了になってから次の作業に進みます。

次にEC2の画面を開きインスタンスの状態が起動中であることを確認します。

最後に事前に作成していたキーペアを使用してインスタンスにSSH接続できることを確認します。

ここまでで実行と動作確認は完了です。

スタックの削除

最後に作成したリソースの削除ですが、AWSマネジメントコンソールからEC2を作成した時とは違い、EC2を直接削除するのではなく、CloudFormationのスタックの削除を実施します。

基本的にはスタックを削除すると、スタックで作成されたリソースがすべて削除されます。

この時S3を作成していてオブジェクトを格納していたりするとエラーになります。

他にも本番環境では運用時に作製されたリソースなどが影響して、スタックの削除ができない場合もありますが、この時も焦らず失敗した理由を読み解き地道に作業を進めていきましょう。

S3のオブジェクトの問題は、スタックの強制削除に同時に削除するということも可能です。

まとめ

今回はCloudFormationを使用して、リソースの作成作業を自動化させました。

今までEC2の作成をマネジメントコンソールから行っていましたが、テンプレートのアップロードとパラメータの選択のみでEC2インスタンスが起動中とできることがわかりました。

ここからRDSも同時に作製したりすることを考えると、とても便利なものだと感じることができます。また、より手順が複雑化した場合でもテンプレートファイル1つで実行できることを考えると、早めのうちに導入しておくと良いかもしれません。

次回は、今回使用したテンプレートにRDSの作成とDjangoの導入までの処理を記述して、サービスが自動で起動するところまで進めたいと考えています。

以上です。

この記事を書いた人

小幡 知弘

1990年茨城県神栖市生まれ
2013年大阪芸術大学卒業
Python×Webエンジニア