Chef 11.10 スタック用のレシピの実装 - AWS OpsWorks

Chef 11.10 スタック用のレシピの実装

Chef 11.10 スタックは、Chef 11.4 スタックと比べて、次のような利点があります。

  • Chef の実行に Ruby 2.0.0 が使用されるため、レシピで新しい Ruby の構文を使用できます。

  • レシピで Chef の検索およびデータバッグを使用できます。

    Chef 11.10 スタックでは、多くのコミュニティクックブックを変更せずに使用できます。

  • クックブックの管理に Berkshelf を使用できます。

    Berkshelf は、カスタムクックブックを管理し、スタックでコミュニティクックブックを使用するための非常に柔軟な方法を提供します。

  • クックブックは、metadata.rb で依存関係を宣言する必要があります。

    クックブックが別のクックブックに依存する場合、その依存関係をカスタムクックブックの metadata.rb ファイルに含める必要があります。たとえば、クックブックに include_recipe anothercookbook::somerecipe のようなステートメントを持つレシピが含まれている場合は、クックブックの metadata.rb ファイルに depends "anothercookbook" という行が含まれている必要があります。

  • AWS OpsWorks スタックは、スタックに MySQL Layer が含まれている場合にのみ、スタックのインスタンスに MySQL クライアントをインストールします。

  • AWS OpsWorks スタックは、スタックに Ganglia Layer が含まれている場合にのみ、スタックのインスタンスに Ganglia クライアントをインストールします。

  • デプロイで bundle install を実行し、インストールが失敗した場合、デプロイも失敗します。

重要

カスタムクックブックまたはコミュニティクックブックに組み込みクックブックの名前を再使用しないでください。組込クックブックと同じ名前のカスタムクックブックは失敗する可能性があります。Chef 11.10、11.4、0.9 のスタックで使用可能な組み込みクックブックの完全なリストについては、「GitHub の opsworks-cookbooks リポジトリ」を参照してください。

非 ASCII 文字が含まれているクックブックは、Chef 0.9 および 11.4 のスタックで正常に実行される場合でも、Chef 11.10 スタックでは失敗する可能性があります。これは Chef 11.10 スタックが、Ruby 1.8.7 よりもエンコードが厳密である Ruby 2.0.0 を使用して Chef を実行するためです。このようなクックブックが Chef 11.10 スタックで正常に実行されるためには、非 ASCII 文字を使用する各ファイルの先頭に、エンコードに関するヒントを提供するコメントを追加する必要があります。たとえば、UTF-8 エンコードの場合、コメントは # encoding: UTF-8 のようになります。Ruby 2.0.0 のエンコードの詳細については、「エンコード」を参照してください。

クックブックのインストールと優先順位

AWS OpsWorks スタッククックブックをインストールする手順は、Chef 11.10 スタックの場合と以前のバージョンの Chef の場合とでは若干異なります。Chef 11.10 スタックの場合、AWS OpsWorks スタックは組み込み、カスタム、および Berkshelf のクックブックをインストールした後、次の順序で一般的なディレクトリにマージします。

  1. 組み込みクックブック。

  2. Berkshelf クックブック (ある場合)。

  3. カスタムクックブック (ある場合)。

AWS OpsWorks スタックは、このマージを実行するときに、レシピを含むディレクトリの内容全体をコピーします。重複がある場合、次のルールが適用されます。

  • Berkshelf クックブックの内容は組み込みクックブックより優先されます。

  • カスタムクックブックの内容は Berkshelf クックブックより優先されます。

このプロセスがどのように機能するかを示すために、3 つのすべてのクックブックのディレクトリに mycookbook という名前のクックブックが含まれている、次のようなシナリオを考えてみます。

  • 組み込みクックブックの mycookbook には、someattributes.rb という名前の属性ファイル、sometemplate.erb という名前のテンプレートファイル、および somerecipe.rb という名前のレシピが含まれています。

  • Berkshelf クックブックの mycookbook には、somerecipe.rbsometemplate.erb が含まれています。

  • カスタムクックブックの mycookbook には somerecipe.rb が含まれています。

マージされたクックブックには次のものが含まれます。

  • 組み込みクックブックの someattributes.rb

  • Berkshelf クックブックの sometemplate.erb

  • カスタムクックブックの somerecipe.rb

重要

組み込みクックブック全体をリポジトリにコピーし、クックブックの一部を変更することによって、Chef 11.10 スタックをカスタマイズしないでください。そうすることで、レシピを含む組み込みクックブック全体が上書きされます。AWS OpsWorks スタックでそのクックブックが更新された場合、手動でプライベートコピーを更新しない限り、スタックで更新のメリットを取得できません。スタックをカスタマイズする方法の詳細については、「AWS OpsWorks スタックのカスタマイズ」を参照してください。

レシピで Chef の search メソッドを使用して、スタックデータのクエリを実行できます。Chef サーバーを対象とする場合と同じ構文を使用しますが、AWS OpsWorks スタックは Chef サーバーにクエリを実行する代わりに、ローカルノードオブジェクトからデータを取得します。これには、以下のデータが含まれます。

  • インスタンスのスタック設定およびデプロイ属性

  • インスタンスの組み込みクックブックとカスタムクックブックの属性ファイルにある属性。

  • Ohai によって収集されるシステムデータ。

スタック設定およびデプロイ属性には、スタック内のオンラインインスタンスのホスト名や IP アドレスなどのデータを含め、通常、レシピが検索で取得する情報の多くが含まれています。AWS OpsWorks スタックでは、各ライフサイクルイベントについてこれらの属性を更新し、正確に現在のスタックの状態が反映されるようにします。つまり、スタック内で検索に依存するコミュニティレシピを、変更せずに、頻繁に使用できます。search メソッドでは適切なデータが返されますが、データはサーバーではなく、スタック設定およびデプロイ属性から取得されます。

AWS OpsWorks スタックの検索の主な制限は、ローカルノードオブジェクト、具体的にはスタック設定およびデプロイ属性のデータのみを処理するという点です。そのため、次のような種類のデータは検索で使用できない可能性があります。

  • 他のインスタンスにあるローカルに定義された属性。

    レシピで属性をローカルに定義している場合、その情報は AWS OpsWorks スタックサービスに報告されないため、検索を使用して他のインスタンスからそのデータにアクセスできません。

  • カスタム deploy 属性。

    アプリケーションをデプロイし、対応する属性がそのデプロイのスタックのインスタンスにインストールされるとき、カスタム JSON を指定できます。ただし、選択したインスタンスにのみデプロイする場合、属性はそのインスタンスにのみインストールされます。それらのカスタム JSON の属性に対するクエリは、他のすべてのインスタンスで失敗します。さらに、カスタム属性は、その特定のデプロイについてのみ、スタック設定およびデプロイ JSON に含められます。カスタム属性にアクセスできるのは、次回のライフサイクルイベントで、新しい一連のスタック設定およびデプロイ属性がインストールされるまでの間だけです。スタックのカスタム JSON を指定する場合、属性は、すべてのライフサイクルイベントについて、すべてのインスタンスにインストールされ、常に検索でアクセスすることができます。

  • 他のインスタンスの Ohai データ。

    Chef の Ohai ツールは、インスタンスでさまざまなシステムデータを取得し、ノードオブジェクトに追加します。このデータはローカルに格納され、AWS OpsWorks スタックサービスに報告されないため、検索で他のインスタンスから Ohai データにアクセスすることはできません。ただし、このデータの一部はスタック設定およびデプロイ属性に含まれる場合があります。

  • オフラインインスタンス。

    スタック設定およびデプロイ属性には、オンラインインスタンスのデータのみが含まれます。

次のレシピの例では、検索を使用して、PHP Layer のインスタンスのプライベート IP アドレスを取得する方法を示します。

appserver = search(:node, "role:php-app").first Chef::Log.info("The private IP is '#{appserver[:private_ip]}'")
注記

AWS OpsWorks スタックでスタック設定およびデプロイ属性データをノードオブジェクトに追加するとき、実際には、レイヤー属性のセットが 2 つ作成されます (各セットのデータは同じです)。1 つのセットは layers 名前空間にあります。AWS OpsWorks スタックでは、データがこのように保存されます。もう 1 つのセットは role 名前空間にあります。Chef サーバーでは同等のデータはこのように保存されます。role 名前空間の目的は、AWS OpsWorks スタックインスタンスで実行するために Chef サーバーに実装されたコードの検索を許可することです。AWS OpsWorks スタックに特化したコードを記述する場合は、前述の例の layers:php-app または role:php-app を使用すると、search は同じ結果を返します。

データバッグの使用

レシピ内で Chef の data_bag_item メソッドを使用して、データバッグ内の情報に対するクエリを実行できます。Chef サーバーを対象とする場合と同じ構文を使用しますが、AWS OpsWorks スタックではインスタンスのスタック設定およびデプロイ属性からデータを取得します。ただし、AWS OpsWorks スタックでは現在 Chef 環境をサポートしていないため、node.chef_environment は常に _default を返します。

カスタム JSON を使用して [:opsworks][:data_bags] 属性に 1 つ以上の属性を追加することによって、データバッグを作成します。次の例では、カスタム JSON にデータバッグを作成するための一般的な形式を示します。

注記

クックブックリポジトリに追加することで、データバッグを作成することはできません。カスタム JSON を使用する必要があります。

{ "opsworks": { "data_bags": { "bag_name1": { "item_name1: { "key1" : “value1”, "key2" : “value2”, ... } }, "bag_name2": { "item_name1": { "key1" : “value1”, "key2" : “value2”, ... } }, ... } } }

通常、スタックにカスタム JSON を指定して、それ以降のすべてのライフサイクルイベントについて、すべてのインスタンスにカスタム属性をインストールします。アプリケーションをデプロイするときにカスタム JSON を指定することもできますが、それらの属性はそのデプロイについてのみインストールされるため、選択した一連のインスタンスにのみインストールされている可能性があります。詳細については、「アプリケーションのデプロイ」を参照してください。

次のカスタム JSON の例は、myapp という名前のデータバッグを作成します。mysql という項目が 1 個と、キーと値のペアが 2 個含まれます。

{ "opsworks": { "data_bags": { "myapp": { "mysql": { "username": "default-user", "password": "default-pass" } } } } }

レシピでこのデータを使用するために、次の例に示すように、data_bag_item を呼び出して、データバッグと値の名前を渡すことができます。

mything = data_bag_item("myapp", "mysql") Chef::Log.info("The username is '#{mything['username']}' ")

データバッグ内のデータを変更するには、単にカスタム JSON を変更するだけで、次のライフサイクルイベントについて、スタックのインスタンスにインストールされます。

Berkshelf の使用

Chef 0.9 および 11.4 スタックでは、カスタムクックブックリポジトリを 1 つだけインストールできます。Chef 11.10 スタックでは、Berkshelf を使用してクックブックとその依存関係を管理でき、これにより複数のリポジトリからクックブックをインストールできます。(詳細については、「ローカルでのクックブックの依存関係のパッケージ化」を参照してください)。 特に、Berkshelf を使用すると、AWS OpsWorks スタック互換のコミュニティクックブックを、使用しているカスタムクックブックリポジトリにコピーすることなく、直接それらのリポジトリからインストールできます。サポートされている Berkshelf バージョンは、オペレーティングシステムによって異なります。詳細については、「AWS OpsWorks Stacks のオペレーティングシステム」を参照してください。

Berkshelf を使用するには、「カスタムクックブックのインストール」に説明されているように、明示的に有効にする必要があります。次に、インストールするクックブックを指定する Berksfile ファイルを、クックブックリポジトリのルートディレクトリに含めます。

Berksfile に外部クックブックソースを指定するには、デフォルトのリポジトリ URL を指定するファイルの先頭部分で source 属性を指定します。明示的にリポジトリが指定されていない限り、Berkshelf はそのソース URL でクックブックを探します。次に、インストールする各クックブックに対応する行を次の形式で追加します。

cookbook 'cookbook_name', ['>= cookbook_version'], [cookbook_options]

cookbook に続くフィールドが特定のクックブックを指定します。

  • cookbook_name – (必須) クックブックの名前を指定します。

    他のフィールドを指定しなかった場合、指定されたソース URL からクックブックがインストールされます。

  • cookbook_version – (オプション) クックブックのバージョンを指定します。

    =>= などのプレフィックスを使用して、特定のバージョンまたは使用可能なバージョンの範囲を指定します。バージョンを指定しない場合、Berkshelf は最新のバージョンをインストールします。

  • cookbook_options – (オプション) 最後のフィールドは、リポジトリの位置などのオプションを指定する 1 つ以上のキーと値のペアを含むハッシュです。

    たとえば、git キーを含めて特定の Git リポジトリを指定したり、tag キーを含めて特定のリポジトリブランチを指定したりすることができます。リポジトリブランチを指定することは、通常、目的のクックブックを確実にインストールするための最適な方法です。

重要

Berksfile に metadata 行を追加し、metadata.rb でクックブックの依存関係を宣言することによって、クックブックを宣言することは避けてください。この処理が正常に実行されるためには、両方のファイルが同じディレクトリにある必要があります。AWS OpsWorks スタックの場合、Berksfile はリポジトリのルートディレクトリに置く必要がありますが、metadata.rb ファイルはそれぞれのクックブックディレクトリに置く必要があります。代わりに、Berksfile 内で外部クックブックを明示的に宣言してください。

次に、クックブックを指定するさまざまな方法を示す Berksfile の例を示します。Berksfile を作成する方法の詳細については、「Berkshelf」を参照してください。

source "https://supermarket.chef.io" cookbook 'apt' cookbook 'bluepill', '>= 2.3.1' cookbook 'ark', git: 'git://github.com/opscode-cookbooks/ark.git' cookbook 'build-essential', '>= 1.4.2', git: 'git://github.com/opscode-cookbooks/build-essential.git', tag: 'v1.4.2'

このファイルは、次のクックブックをインストールします。

  • コミュニティクックブックリポジトリにある apt の最新バージョン。

  • バージョン 2.3.1 以降である場合に限り、コミュニティクックブックにある bluepill の最新バージョン。

  • 指定されたリポジトリにある ark の最新バージョン。

    この例の URL は GitHub のパブリックコミュニティクックブックのリポジトリ用ですが、プライベートリポジトリなど、他のリポジトリからクックブックをインストールできます。詳細については「Berkshelf」を参照してください。

  • 指定されたリポジトリの v1.4.2 ブランチにある build-essential クックブック。

カスタムクックブックリポジトリには、Berksfile に加えて、カスタムクックブックを含めることができます。その場合、AWS OpsWorks スタックは両方のクックブックをインストールします。これは、インスタンスが 3 つのクックブックリポジトリを持つことができることを意味します。

  • 組み込みクックブックは、/opt/aws/opsworks/current/cookbooks にインストールされます。

  • カスタムクックブックリポジトリにクックブックが含まれる場合、そのクックブックは /opt/aws/opsworks/current/site-cookbooks にインストールされます。

  • Berkshelf を有効にし、カスタムクックブックリポジトリに Berksfile が含まれる場合、指定されたクックブックは /opt/aws/opsworks/current/berkshelf-cookbooks にインストールされます。

組み込みクックブックとカスタムクックブックは、セットアップ時に各インスタンスにインストールされますが、それ以降は、[Update Custom Cookbooks] スタックコマンドを手動で実行しない限り、更新されません。AWS OpsWorks スタックは Chef を実行するたびに berks install を実行するため、Berkshelf クックブックは、以下のルールに従って、各ライフサイクルイベントについて更新されます。

  • リポジトリに新しいバージョンのクックブックがある場合、このオペレーションは、リポジトリからのクックブックを更新します。

  • それ以外の場合、このオペレーションは、ローカルキャッシュから Berkshelf クックブックを更新します。

注記

このオペレーションは Berkshelf クックブックを上書きするため、クックブックのローカルコピーを変更している場合、その変更内容が上書きされます。詳細については「Berkshelf」を参照してください。

また、Berkshelf クックブックとカスタムクックブックの両方を更新する [Update Custom Cookbooks] スタックコマンドを実行することによって、Berkshelf クックブックを更新することもできます。