AWSIaC

CloudFormationでec2のcfn-initを使ったデバック方法

AWS

CloudFormationでEC2インスタンスへパッケージを自動インストールセットする際には、UserDataを利用する必要があります。

UserDataを利用した方法については以下でメモしています。
https://syachiku.net/ec2-userdata/

ただし、このUserDataを利用してセットアップをしていて途中で失敗した場合、失敗したスタック削除→再度作成を繰り返しながらデバックをしていく必要があります。

※私の場合は、基本的には一発で成功することはなく、トライ&エラーを何回も繰り返します・・・

EC2インスタンス自体が作り直しになるため、作成までの待ち時間が多いことやIPアドレスがその都度変わるなど、かなりの非効率なデバック方法になってしまいます。

そこで、ヘルパースクリプト cfn-init を利用することで作り直しをする必要なく効率的にデバックする方法について紹介いたします。

1. CloudFormationのヘルパースクリプトとは

まずはじめに CloudFormationのヘルパースクリプトについて簡単に説明します。

CloudFormationのヘルパースクリプトは スタック内のEC2インスタンスの構築・変更等を便利にする機能を提供しています。

CloudFormation ヘルパースクリプトリファレンス - AWS CloudFormation
AWS CloudFormation でソフトウェアをインストールしたりサービスを開始したりするために使用できる Python ヘルパースクリプトについて説明します。

ヘルパースクリプトは全部で以下の4種類があります

  • cfn-init: リソースメタデータの取得と解釈、パッケージのインストール、ファイルの作成、およびサービスの開始で使用します。
  • cfn-signal: CreationPolicy または WaitCondition でシグナルを送信するために使用し、前提となるリソースやアプリケーションの準備ができたときに、スタックの他のリソースを同期できるようにします。
  • cfn-get-metadata: 特定のキーへのリソースまたはパスのメタデータを取得するために使用します。
  • cfn-hup: メタデータへの更新を確認し、変更が検出されたときにカスタムフックを実行するために使用します。

Amazon Linux AMI には標準でインストール済みとなっています。

もし、追加でインストールする場合には「yum install aws-cfn-bootstrap」にてインストールすることができます。

2. cfn-initを利用した効率的なデバック方法

cfn-initを利用した効率的なデバック方法について実際に試して見たいと思います。

2.1. 今回の流れ

図にするとこんな感じになります。

2.2. エラーを発生させてみる

まずは以下のCloudFormationテンプレートを使ってEC2インスタンスを作成して自動セットアップを行います。 MetadataとUserDataの一部を抜粋して記載します。

基本的なテンプレートは以下の記事で書いてある通りです。 
https://syachiku.net/ec2-userdata/

UserData側でcfn-initを呼び出ししてから、cfn-initによってhttpdとmysqlをインストールするようにしています。

Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Metadata:
      Comment: Install a simple web app
      AWS::CloudFormation::Init:
        configSets:
          InstallAndRun:
            - Install
        Install:
          packages:
            yum:
              httpd: []
              mysql: []

(省略)

    UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash -xe
            yum update -y

            # cfn-init
            /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --configsets InstallAndRun --resource Ec2Instance --region ${AWS::Region}

そうするとEC2インスタンス自体は作成されますが、cfn-init途中のmysql-serverをインストールする際にエラーになってしまいます。

cfn-initが実行された際のログはEC2インスタンスへログオンしてから「/var/log/cfn-init.log」で確認することができます。

mysqlパッケージががインストールできなかった様です。

Error occurred during build: Yum does not have mysql available for installation

とりあえずエラーを解消するためにコメントアウトします。

Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Metadata:
      Comment: Install a simple web app
      AWS::CloudFormation::Init:
        configSets:
          InstallAndRun:
            - Install
        Install:
          packages:
            yum:
              httpd: []
#              mysql: []

2.3. スタックを更新する

テンプレートを更新した後に、CloudFormationからStackを更新します。

そうすると先ほどのメタデータ部分が更新されます。 EC2インスタンス側には何も起こってません。

2.4. cfn-initコマンドを手動で実行する

先ほど更新したメタデータを使って再度cfn-initを手動で実行してみます。

EC2インスタンス内で手動で以下のコマンドを実行します。
※スタック名とリージョンなどは自身の環境に合わせて変更してください。

# /opt/aws/bin/cfn-init -v --stack <スタック名> --configsets InstallAndRun --resource Ec2Instance --region <リージョン>

そうすると再度cfn-initで書かれた処理が実行されます。

# cat /var/log/cfn-init.log
(省略)
2021-09-03 02:59:51,120 [INFO] ConfigSets completed
2021-09-03 02:59:51,120 [DEBUG] Not clearing reboot trigger as scheduling support is not available
2021-09-03 02:59:51,120 [INFO] -----------------------Build complete-----------------------

エラーが発生しなくなり、ログからも想定した通りの動作となりました。

3. まとめ

UserDataだけを利用することも可能ですし、cfn-initを必ずしも使う必要はありません。

ただし、複雑な処理が多くなってきた場合には、今回のようにデバックのし易さなどの理由でcfn-initを使うほうがオススメです。

失敗したスタック削除→再度作成を繰り返しているとかなり時間かかります。

AWSを効率的に学習する方法

私がAWSを学習するために使った学習材料は「Udemy」だけです。

まずは座学を行ってAWSプラクティショナー もしくは ソリューションアーキテクト試験を取得することを目標にしました。

具体的にはUdemyで以下の2つの商材を購入して学習しました。AWS公式が提供している模擬試験も受けていません。

Udemyは世界最大級のオンライン学習プラットフォームで、世界中の学びたい人と教えたい人をオンラインでつなぐサービスです。 Udemyは米国Udemy,Inc.が運営するプラットフォームで日本ではベネッセが事業パートナーとして協業をしています。 C2C(consumer to consumer)により生まれる豊富で多彩な講座により個人の学習ニーズに応じた学びをみつけることができます。

これだけでOK! AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座(SAA-C02試験対応版)
【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集(6回分390問)

今回は以上となります。

コメント

タイトルとURLをコピーしました