Amazon Web Services ブログ

CloudFormation で cfn-init に代えて State Manager を利用する方法とその利点

はじめに

AWS CloudFormationを介してAmazon Elastic Cloud Compute (EC2) インスタンスをデプロイした後には、ソフトウェアのインストール、またはオペレーティングシステムの設定が必要になることがほとんどです。多くのAWSのお客様はCloudFormationのヘルパースクリプトの一つである cfn-init (2012年2月から利用可能)を使用していると思います。しかし、それ以後もAWSは、お客様のフィードバックに応じて多くの新機能とサービスをリリースしてきました。そのうちの一つはAWS Systems Managerです。このブログ記事では、AWS CloudFormationを介してデプロイされたAmazon EC2インスタンスに対して、AWS Systems Manager State Managerを使用してインスタンスを設定する、よりシンプルで堅牢な方法を紹介します。

State Managerの概要

Systems Manager State Managerは、 Amazon EC2とオンプレミスのインフラストラクチャをユーザーが定義した状態に保つ設定管理サービスです。設定プロセスは自動化されスケーラブルに処理することが可能です。State Managerを使用すると、EC2インスタンス起動時にソフトウェアを立ち上げ、ネットワーク設定を行い、WindowsインスタンスをMicrosoft Active Directory ドメインに参加させ、WindowsまたはLinuxのマネージドインスタンス(訳注: AWS Systems Managerの管理下にあるサーバー)でスクリプトを実行できます。State Managerでそれらのタスクを実行するには、自動化ドキュメントまたはコマンドドキュメントをターゲットインスタンスにマップする関連付けを作成します。State Managerを使用すると、cfn-initと同様に多くのタスクを実行できますが、さらに追加のメリットがあります。

  1. ログをAmazon Simple Storage Service (S3)に集約
  2. CloudFormationテンプレートの簡素化
  3. 設定コンプライアンスの可視性の向上
  4. AWS CloudTrailと統合され改善された監査
  5. 初期プロビジョニング後のスケジュールに基づく設定
  6. タグを使用して起動された新しいインスタンスの設定
  7. 同時実行値とエラーしきい値の設定

この記事では、最初の4つの利点に焦点をあてます。最初の利点は、トラブルシューティングのために、ログをS3に集約できることです。cfn-initはEC2インスタンスのローカルにログを出力するため、トラブルシュートのためにリモートからインスタンスにアクセスする必要があります。一方State Managerで関連付けを作成すると、Amazon S3にログ出力を集約できます。これにより、CloudFormationスタックの各インスタンスにログインしなくても大規模なトラブルシュートを簡単に行うことができます。

二番目の利点は簡素化されたCloudFormationテンプレートです。cfn-initでは、実行するタスクの詳細をCloudFormationテンプレートのリソース内のMetadataセクションに指定する必要があります。次に、メタデータ情報を読み取るために、起動時にcfn-initをポイントする必要があります。さらに設定の一部でスクリプトのダウンロードが必要な場合、複数のステップが必要になります。一方State Managerには、ネイティブのCloudFormationリソースタイプがあり、CloudFormationテンプレート内の複雑さを減らすのに役立ちます。aws:downloadContent プラグインを使用してGitHubまたはAmazon S3からスクリプトを自動的にダウンロードする多くのSystems Managerドキュメントがあり、それらを実行できます。これにより、CloudFormationから設定スクリプトを分離し、1つのステップでダウンロードと実行ができます。

三番目の利点は、State Managerがインスタンスの設定を継続的に維持し、それを保証できることです。これに対しcfn-initはCloudFormationスタックの作成または更新時(更新用に適切に設定されている場合)に実行されるだけで、その状態の検証は自分で行う必要があります。使用する設定ツールによっては、State Managerを使用してコンプライアンス情報を取得することもできます。

最後の利点は、全てのアクションがCloudTrailを介して追跡されることです。これにより、cfn-initよりも監査性が改善されます。

まとめます。まず、CloudFormationを使用することが、AWSリソースを定義する推奨のプラクティスです。そしてリソースがインスタンスの場合は、SystemsManagerを使用することを推奨します。ここまでで、このパターンの利点について説明してきました。次に、それをどのように実践できるかを見てみましょう。 次のセクションでは、State Managerを介してGitHubに保存されているAnsibleプレイブックをAmazon Linux 2インスタンスで実行する方法を説明します。

図1: CloudFormationとState Managerを一緒に使用する

CloudFormationでState Managerを使用してNGINXをインストールする

State Managerには、AWS::SSM::AssociationというCloudFormationのリソースタイプがあり、それはState Managerの関連付けを作成します。このリソースタイプは、CloudFormationによってデプロイされたインスタンスに対して、設定スクリプトまたは自動化ワークフローをトリガーできます。このリソースタイプには、WaitForSuccessTimeoutSecondsと呼ばれるプロパティがあり、State Managerによって関連付けが正常に適用されるまで待機します。この例では、ターゲットインスタンスで、AWS-ApplyAnsiblePlaybooks コマンドドキュメントを実行する関連付けを作成しています。

  AnsibleAssociation:
    Type: AWS::SSM::Association
    Properties:
      # ここではAWS-ApplyAnsiblePlaybooksを使用しています
      Name: AWS-ApplyAnsiblePlaybooks
      # CloudFormationは関連付けが行われるのを待ちます
      WaitForSuccessTimeoutSeconds: 120
      Targets:
        - Key: InstanceIds
          Values: [ !Ref EC2Instance ]
      OutputLocation:
        S3Location: 
          OutputS3BucketName: !Ref SSMAssocLogs
          OutputS3KeyPrefix: 'logs/'
      Parameters:
        # GitHubからAnsibleプレイブックを取得します
        SourceType:
          - 'GitHub'
        # 少なくとも次の情報が必要です。プライベートリポジトリを使用する場合は、GitHub Tokenも必要です。 
        SourceInfo:
          - '{"owner":"<Insert your GitHub Owner Name>",
              "repository":"<Insert your GitHub Repo>",
              "path":"",
              "getOptions":"branch:master" }'
        # Ansibleと依存関係のインストール
        InstallDependencies:
          - 'True'
        # 実行するプレイブック
        PlaybookFile:
          - 'playbook.yml'
        ExtraVariables:
          - 'SSM=True'
        Check:
          - 'False'
        Verbose:
          - '-v'

このテンプレートによって作成されたCloudFormationスタックは、コマンドドキュメントとEC2インスタンスの関連付けを行います。EC2インスタンスがSystems Managerサービスに登録されると、GitHubからAnsibleプレイブックをダウンロードするコマンドドキュメントを実行し、Ansibleをインストールしてプレイブックを実行します。リソースタイプは、成功または失敗をCloudFormationに伝えます。

これはAnsibleを使用するパターンを示すシンプルな例ですが、AWS-RunRemoteScriptまたはスクリプトを実行する他のSystems Managerドキュメントを使用して、リモートからスクリプトを実行することもできます。この例では、インスタンスを設定する際の、一回のトリガーに注目しました。しかし、もしインスタンスのライフサイクル全体で設定の維持を確実にしたい場合はどうでしょうか?

State Managerは、スケジュール実行の設定もでき、毎日実行するようにリソースにcron式を渡すことができます。スクリプトが冪等な振る舞いで書かれている場合は、それを実行して設定を確実にすることができます。State Managerは、PowerShell Desired State Configuration (PowerShell DSC)ChefSaltStackAnsible等の冪等性を扱う設定管理ツールの使用もサポートしています。既にAWS-ApplyAnsiblePlaybooksドキュメントを紹介しましたが、PowerShell DSCのためのAWS-ApplyDSCMofs、Chef recipesのためのAWS-ApplyChefRecipes、 Salt StatesのためのAWS-RunSaltState (Blog Post)等、他にも多くのドキュメントがあります。公開されているSystems Managerドキュメントの一部では、AWS-RunInSpecChecksやAWS-ApplyDSCMofsなどの、コンプライアンスの逸脱に関するレポートが可能なものもあります。

 

CloudFormationでState Managerを使用する多くのサンプル

新しいパターンやサービスを学ぶときには、多くの実用的な例があると役に立ちます。このブログ記事では、CloudFormationによってデプロイされたインスタンスを設定する際に、cfn-initに代えてState Managerを使用する方法の一例を紹介しました。我々はAWS::SSM::Associationリソースタイプを使ったCloudFormationテンプレートをこちらのリポジトリで紹介しています。このリポジトリにはbashスクリプトを実行したり、Active Directoryドメインに参加する実例もあります。今後、さらに多くの実例を掲載したいと考えています。サンプルに問題があったり、また必要なサンプルがあれば、リポジトリのIssueに投稿してください。

 

結論

CloudFormationとState Managerの組み合わせには多くのパターンがありますが、我々が推奨するのは、CloudFormationでAWSリソースを定義し、Systems Managerを使ってOS上の設定管理を実施する方法です。AWS CloudFormationを初めて使用する場合も、以前から使用している場合も、cfn-initの代わりにState Managerを使用することを検討してください。State Managerを使うことで、複雑なCloudFormationテンプレートを簡素化するのを助け、CloudFormationから既存の設定管理ツールをより使いやすくし、複数のノードに渡るトラブルシュートを容易にします。

 

著者について

Aaron Limaは、ニューヨークエリアに拠点を置くAmazon Web Servicesのシニアソリューションアーキテクトです。Aaronは、AWS for Windows及びマイグレーションの分野でお客様を支援しています。Aaronは20年以上の経験を持つITプロフェッショナルであり、一度限りの支援で顧客がAWSクラウドを利用することを実現することに情熱を注いでいます。Aaronの主な関心は、AWSでの管理とガバナンスです。Aaronは、AWS Systems Manager、AWS CloudFormation、AWS Config、インフラストラクチャのデプロイと運用の自動化について話すことが大好きです。

 

原文はこちら。翻訳はSA木村(友)が担当しました。