前書き

管理者は、DigitalOceanメタデータサービスを使用して、新しいサーバーが自動的に構成できるようにする指示を提供できます。 これは便利ですが、多くの組織は、ChefやPuppetなどの構成管理ツール内ですべてのインフラストラクチャ構成を処理することを好みます。

このガイドでは、メタデータサービスとCloudInitを使用して既存の構成管理展開に接続するDigitalOceanサーバーをブートストラップする方法を示します。 サーバーの実際の構成は、構成管理サービスによって処理できます。 ChefノードとPuppetノードの両方をブートストラップする方法を示します。

前提条件

このガイドを完了するには、DigitalOceanメタデータサービスに精通している必要があります。 https://www.digitalocean.com/community/tutorials/an-introduction-to-droplet-metadata [このガイド]で、メタデータサービスに情報を入力したり、メタデータサービスから情報を取得したりする方法の詳細を確認できます。

このガイドでは、初回起動時にDropletのCloudInitサービスによって消費される「+ cloud-config 」という種類のスクリプトを活用して、初回実行の設定を行います。 このガイドに記載されているスクリプトを変更する方法をよりよく理解するには、 ` cloud-config +`スクリプト、その構文、および動作に関する基本的な知識が必要です。 cloud-configスクリプトの概要については、https://www.digitalocean.com/community/tutorials/an-introduction-to-cloud-config-scripting [こちら]をご覧ください。 より実用的な例については(形式の制限に関するいくつかの議論と共に)、cloud-config こちら

Cloud-Configスクリプトを使用してChefノードをブートストラップする

DigitalOceanメタデータサービスを使用すると、 `+ cloud-config +`スクリプトを使用して、新しいサーバーを既存のChef制御インフラストラクチャに簡単にフックできます。

このシステムに新しいサーバーを追加するには、新しいサーバーが接続して構成手順を受け取ることができるように、Chefサーバーが既に構成されている必要があります。 Chefサーバーと管理ワークステーションの展開についてサポートが必要な場合は、https://www.digitalocean.com/community/tutorials/how-to-install-a-chef-server-workstation-and-client-on-ubuntuをフォローできます。 -vps-instances [このガイド]を開始します。

一般計画

新しいサーバーがオンラインになったら、Chefサーバーの制御下に置く必要があります。 通常、これは、「+ knife 」管理コマンドを使用して新しいサーバーに接続し、「 bootstrap +」サブコマンドを使用して実行できます。 これにより、新しいサーバーに接続し、Chefクライアントと検証資格情報をインストールして、新しいノードがChefサーバーに接続できるようにします。 その後、Chefクライアントはサーバーに接続し、自身を検証し、新しいクライアント資格情報を受信し、サーバーから構成をプルダウンし、必要な状態にするために必要なアクションを実行します。

このガイドでは、 `+ cloud-config +`スクリプトを使用して手動ブートストラップ手順を置き換え、新しいノードが自動的にChefサーバーに接続し、それ自体を検証し、クライアント認証情報を受信し、最初のChefクライアント実行を実行できるようにします。 サーバーは、管理者の手動の支援なしで、最初のブート時にこれを自動的に行います。

ナイフ設定ファイルから必要なデータを収集する

`+ cloud-config `スクリプトが正常にブートストラップするためには、 ` knife +`コマンドで通常利用できる認証情報にアクセスする必要があります。 具体的には、次の情報が必要です。

  • シェフ検証名

  • 検証キー

  • ChefサーバーにアクセスできるURL

この情報はすべて、正しい形式で、Chefインフラストラクチャの管理に使用されるワークステーションの「+ knife 」設定ファイルで入手できます。 Chefリポジトリの内部には、このファイルを含む ` .chef +`という隠しディレクトリがあるはずです。

Chefリポジトリがワークステーションのホームディレクトリにあり、 `+ chef-repo +`と呼ばれると仮定すると、次のように入力してファイルの内容を出力できます。

cat ~/chef-repo/.chef/knife.rb

必要な情報は次のとおりです。

current_dir = File.dirname(__FILE__)
log_level                :info
log_location             STDOUT
node_name                "jellingwood"
client_key               "#{current_dir}/jellingwood.pem"
validation_client_name   ""
validation_key           ""
chef_server_url          ""
syntax_check_cache_path  "#{ENV['HOME']}/.chef/syntaxcache"
cookbook_path            ["#{current_dir}/../cookbooks"]

検証名とChefサーバーのURLは、そのままファイルから直接取得できます。 これらの値をコピーして、 `+ cloud-config +`ファイルで使用できるようにします。

`+ validation_key `は、実際のキーが保持されている場所を指します。 上記の例では、これは ` knife.rb `ファイルと同じディレクトリにあり、 ` digitalocean-validator.pem +`と呼ばれることを示しています。 これは、構成によって異なる可能性があります。

このファイルの内容が必要なので、 `+ cat +`コマンドを再度使用してください。 検証キーに指定された場所を指すようにコマンドを変更します。

cat

RSA秘密鍵が表示されます。

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3O60HT5pwEo6xUwcZ8WtExBUhoL3bTjlsvHVXg1JVmBUES+f
V9jLu2N00uSZEDZneCIQyHLBXnqD/UNvWEPNvPzt1ecXzmw2BytB7lPDW4/F/8tJ
vAVrKqC7B04VFGmcFY2zC8gf8BWmX8CNRDQooM7UO5OWe/H6GDGPPRIITerO3GrU

. . .

sWyRAoGBAKNc/ZUM8ljRV0UJxQ9nbdozXRZjtUaNgXMNiw+oP2HYYdHrlkKnGHYJ
Js63rvjpq8pocjE8YI+2H0v4/4uWqW8GEBfrWbLMzGsYPnRyiHR5+hgjCUU50RB3
eFoNbURwLYcq2Z/IAQZpDpJWpofz3OVMpMXtei1cIflrAAd2wtWO
-----END RSA PRIVATE KEY-----

検証キー全体をコピーして、 `+ cloud-config +`スクリプトで一時的に使用できるようにします。

基本的なCloud-Config Chefクライアントのインストール

上記のデータを取得したら、スクリプトを作成できます。 Chefの設定は、「+ chef」という名前の専用の「+ cloud-config」モジュールを使用して実行できます。 `+ cloud-config `には有効なYAMLを含める必要があり、スクリプトの最初の行として `#cloud-config +`を含める必要があります。

開始すると、スクリプトは次のようになります。

#cloud-config
chef:

`+ cloud-config +`ドキュメントは、Ruby gem、パッケージ、または従来の「オムニバス」インストール方法のいずれかからChefクライアントをインストールできると主張しています。 ただし、実際には、gemメソッドとpackageメソッドの両方が失敗する傾向があるため、「オムニバス」メソッドを使用します。 通常は必要ありませんが、omnibusインストーラーの場所も明示的にリストします。

`+ force_install +`を「false」に設定します。 このように、何らかの理由でChefクライアントが既にイメージにインストールされている場合(たとえば、スナップショットからデプロイする場合)、クライアントは再インストールされません。 これまでのところ、スクリプトは次のようになります。

#cloud-config
chef:
 install_type: "omnibus"
 omnibus_url: "https://www.opscode.com/chef/install.sh"
 force_install: false

次に、 `+ node_name +`ディレクティブを使用して、Chefインフラストラクチャ内の新しいサーバーの名前を選択するオプションがあります。 これを設定しない場合、Chefはサーバーのホスト名を使用するため、これはオプションです。 ただし、これはChef環境で一意でなければなりません。

その後、Chefワークステーションから取得したすべての接続情報を追加できます。 `+ server_url `オプションを、 ` knife.rb `ファイルとまったく同じようにChefサーバーの場所に設定します。 同じことが ` validation_name +`オプションにも当てはまります。

検証キーには、YAMLパイプ記号( + | +)を使用して、ワークステーションで見つかった検証キー全体を入力します。

#cloud-config
chef:
 install_type: "omnibus"
 omnibus_url: "https://www.opscode.com/chef/install.sh"
 force_install: false
 node_name: ""
 server_url: ""
 validation_name: ""
 validation_key: |

この時点で、スクリプトには、Chefサーバーに接続してクライアント認証情報を作成するために必要なすべての認証があります。

Chef環境、run_list、および属性の構成

上記の詳細は、クライアントがChefサーバーに接続するのに十分な情報を提供しますが、実際の設定方法に関する情報はノードに提供していません。 この情報は `+ cloud-config +`スクリプトでも提供できます。

新しいノードを配置する環境を指定するには、 `+ environment`オプションを使用します。 これが設定されていない場合、 `+ _default +`環境が設定されます。これは、別の環境が与えられていないChefノードの一般的なデフォルトです。

chef:
 environment: ""

`+ run_list +`は、クライアントが順番に適用する必要があるアイテムの単純なリストとして指定できます。 これらは、レシピまたはロールのいずれかです。

chef:
 run_list:
   - ""
   - ""

`+ initial_attributes `階層を使用して、新しいノードの初期属性を指定できます。 これにより、 ` run_list +`の適用方法に影響する初期属性が設定されます。

chef:
 initial_attributes:

前の `+ cloud-config +`スクリプトに接続すると、次のようになります。

#cloud-config
chef:
 install_type: "omnibus"
 omnibus_url: "https://www.opscode.com/chef/install.sh"
 force_install: false
 node_name: ""
 server_url: ""
 validation_name: ""
 validation_key: |











 environment: ""
 run_list:
   - ""
   - ""
 initial_attributes:

出力のリダイレクトとChef Client Runの構成

上記のスクリプトには、 `+ chef:`セクションで必要なすべての情報が含まれています。 ただし、他のいくつかの ` cloud-config`モジュールを使用して行うべきことがいくつかあります。

まず、すべてのコマンドとサブコマンドからの出力をCloudInitプロセスの出力ログにリダイレクトすることを指定する必要があります。 これはデフォルトで `+ / var / log / cloud-init-output.log `にあります。 次のように ` output +`モジュールでこれを行うことができます:

output: {all: '| tee -a /var/log/cloud-init-output.log'}

もう1つやりたいことは、Chefクライアントをインストールして構成したら、実際に実行されるように設定することです。 これを書いている時点では、オムニバスのインストール方法はこれを自動的に行いません。

コマンドを呼び出す前に、 `+ chef-client `実行可能ファイルがサーバーにインストールされるまで待機することで、この動作を強制できます。 単純な ` bash `ループを使用して、5秒ごとにこのファイルの存在を確認します。 見つかったら、指定した初期設定を実装するために ` chef-client`を実行します。

`+ runcmd `モジュールを使用して、任意のコマンドを発行できます。 これは、 ` bash +`ループの理想的な場所です。

runcmd:
 - while [ ! -e /usr/bin/chef-client ]; do sleep 5; done; chef-client

また、オプションで、最初の起動後にメタデータエンドポイントをnullルーティングするために、別の `+ cloud-config +`ディレクティブを追加できます。 これは、ユーザーデータに秘密キーを入れているため便利です。 メタデータエンドポイントをnullルーティングしないと、サーバー上のすべてのユーザーがアクセスできます。 以下を追加してこれを実装します。

disable_ec2_metadata: true

これらをこれまでに構築したスクリプトと組み合わせることで、ノードをブートストラップしてChefインフラストラクチャに接続するために必要な完全なスクリプトを取得できます。

#cloud-config
chef:
 install_type: "omnibus"
 omnibus_url: "https://www.opscode.com/chef/install.sh"
 force_install: false
 node_name: ""
 server_url: ""
 validation_name: ""
 validation_key: |











 environment: ""
 run_list:
   - ""
   - ""
 initial_attributes:






output: {all: '| tee -a /var/log/cloud-init-output.log'}
runcmd:
 - while [ ! -e /usr/bin/chef-client ]; do sleep 5; done; chef-client
disable_ec2_metadata: true

上記のスクリプトは、インフラストラクチャ内の新しいサーバーごとに必要に応じて調整できます。

Cloud-Configスクリプトを使用してPuppetノードをブートストラップする

インフラストラクチャが設定管理のためにPuppetに依存している場合、代わりに `+ puppet `モジュールを使用できます。 Chefの例のように、Puppetノードのブートストラップには、「 cloud-config +」を使用して新しいサーバーを既存の構成管理インフラストラクチャに接続することが含まれます。

始める前に、インフラストラクチャ用にPuppetマスターサーバーを設定しておく必要があります。 Puppetサーバーの起動と実行についてサポートが必要な場合は、https://www.digitalocean.com/community/tutorials/how-to-install-puppet-to-manage-your-server-infrastructure [このガイド]をご覧ください。

一般計画

新しいPuppetサーバーがオンラインになると、Puppetマスターサーバーと通信できるようにPuppetエージェントがインストールされます。 このエージェントは、ノードの望ましい状態を指示する情報を受信および適用する役割を果たします。 これを行うために、エージェントはマスターに接続し、それ自体に関するデータをアップロードし、目的の状態を説明する現在のカタログをプルダウンし、その状態に到達するために必要なアクションを実行します。

ただし、これが発生する前に、最初の実行時に、エージェントはマスターサーバーに自身を登録する必要があります。 証明書署名要求を作成し、マスターに送信して署名します。 通常、エージェントは証明書に署名するまで定期的にマスターに再接続しますが、環境に適している場合は特定の特性で着信リクエストに自動的に署名するようにPuppetを設定できます(これについては後で説明します)。

`+ cloud-config`スクリプトを使用して、初めてマスターに接続するために必要な情報で新しいサーバーを設定します。 その時点で、カタログの形式でPuppetマスターサーバーから設定の詳細を取得できます。

操り人形マスターから必要なデータを収集する

`+ cloud-config +`ファイルを作成する前に最初に行う必要があるのは、接続する必要があるPuppetマスターサーバーからデータを収集することです。 必要な情報はわずかです。

まず、Puppetマスターサーバーの完全修飾ドメイン名(FQDN)を取得する必要があります。 これを行うには、次のように入力します。

hostname -f

ほとんどの場合、次のような結果が返されます。

puppet.

Puppetマスター設定ファイルをチェックして、 `+ dns_alt_names +`オプションが設定されているかどうかを確認することもできます。

cat /etc/puppet/puppet.conf
. . .

dns_alt_names = puppet,puppet.

. . .

これらのオプションを設定した後にPuppetマスターのSSL証明書が生成された場合、それらも使用できる可能性があります。

収集する必要があるもう1つのアイテムは、Puppetマスターの認証局証明書です。 これは、 `+ / var / lib / puppet / ssl / certs / ca.pem `または ` / var / lib / puppet / ssl / ca /​​ ca_crt.pem +`にあります。

sudo cat /var/lib/puppet/ssl/certs/ca.pem

結果は次のようになります。

-----BEGIN CERTIFICATE-----
MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC

. . .

arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
-----END CERTIFICATE-----

証明書全体をコピーします。 これを `+ cloud-config +`ファイルに含めて、新しいサーバーが正しいPuppetマスターに接続していることを確認できるようにします。

これらの情報を取得したら、新しいサーバーが既存のPuppetインフラストラクチャにプラグインできるように、 `+ cloud-config +`ファイルの構築を開始できます。

基本的なCloud-Config Puppetノードのインストール

新しいPuppetノードの `+ cloud-config `設定は非常に簡単です。 すべてのPuppet固有の設定は、ファイルの ` puppet:`セクション内にあります。 すべての ` cloud-config `ファイルと同様に、最初の行には単独で `#cloud-config +`を含める必要があります。

#cloud-config
puppet:

この下には、2つのサブセクションしかありません。 最初は `+ ca_cert +`キーです。 これは、パイプ文字を使用してYAMLテキストブロックを開始し、CA証明書全体をインデントされたブロックとして提供できるようにします。

#cloud-config
puppet:
 ca_cert: |
   -----BEGIN CERTIFICATE-----
   MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
   ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
   GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC

   . . .

   arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
   rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
   l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
   UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
   -----END CERTIFICATE-----

証明書全体と開始マーカーと終了マーカーを必ず含めて、適切にインデントしてください。

`+ puppet:`傘の下の2番目のセクションは ` conf:`セクションです。 これは、一般的な ` puppet.conf `ファイルに追加されるキーと値のペアを指定するために使用されます。 キーと値のペアは、 ` puppet.conf +`ファイルにあるように、セクションヘッダーの下に配置する必要があります。

たとえば、少なくとも、新しいサーバーはPuppetマスターサーバーのアドレスを知る必要があります。 `+ puppet.conf `ファイルでは、これは次のように ` [agent] +`セクションの下にあります。

. . .

[agent]
server = puppet.

. . .

これを `+ cloud-config +`構文で指定するには、これまでの内容に追加します:

#cloud-config
puppet:
 ca_cert: |
   -----BEGIN CERTIFICATE-----
   MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
   ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
   GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC

   . . .

   arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
   rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
   l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
   UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
   -----END CERTIFICATE-----
 conf:
   agent:
     server: "puppet."

`+ conf:`セクションは ` ca_cert `セクションとインラインであり、子要素ではないことに注意してください。 これは、Puppetマスターに接続するために最低限必要なものです。 ` puppet.conf +`にある追加の構成アイテムは、最初にセクション名のレベルを作成し、次にキーと値のペアを定義することにより、同様の方法で追加できます。

この後、今後のすべての出力を `+ cloud-init-output.log `ファイルにリダイレクトし、Chef configに追加したものと同等の ` runcmd `行を追加する必要があります。 これは、Puppetエージェントがインストールされるまで待機してから、それを有効にして再起動します。 Chefセクションで行ったように、最初の実行後にメタデータエンドポイントをnullルーティングすることもできます。 これらの行の ` cloud-config +`ディレクティブは、他のモジュールセクションの外側に配置する必要があります。

. . .

 conf:
   agent:
     server: "puppet."
output: {all: '| tee -a /var/log/cloud-init-output.log'}
runcmd:
 - while [ ! -e /usr/bin/puppet ]; do sleep 5; done; puppet agent --enable; service puppet restart
disable_ec2_metadata: true

この情報を使用して、新しいサーバーはPuppetマスターサーバーに接続し、クライアント証明書署名要求を生成してマスターに転送できます。 デフォルトでは、クライアント証明書はPuppetマスターで手動で署名する必要があります。 これが完了すると、次のPuppetエージェントの更新間隔(デフォルトでは30分ごと)で、ノードはPuppetマスターから構成をプルダウンします。 この遅延を回避するために、比較的安全な自動署名メカニズムを実装する方法について少し後で説明します。

ノードの証明書名の定義

新しいサーバーの `+ puppet.conf `ファイルに配置できる値の1つは、一意のケースです。 ` cloud-config `ファイルでは、特定の変数が指定されている場合、 ` certname +`オプションで環境の値を置き換えることができます。 次の変数が認識されます。

  • * +%i + *:サーバーのインスタンスID。 これは、サーバーの作成時に `+ http:// 169.254.169.254 / metadata / v1 / id +`から取得されます。 これは、ドロップレットを一意に識別するために使用されるドロップレットIDに対応します。

  • * +%f + *:サーバーのFQDN。

これを念頭に置いて、一般的な `+ certname +`設定は次のようになります。

#cloud-config
puppet:

. . .

 conf:
   agent:
     server: "puppet."
     certname: ""

これにより、次のようなパターンの `+ certname +`が生成されます。

  |-Droplet ID
  |
  |            |-Fully Qualified Domain Name
  |            |
|-----||-------------------|

次のセクションで説明するように、「+ certname +」の一部としてDroplet IDを使用すると、安全なPuppet自動署名を設定するのに役立ちます。

Puppet証明書の自動署名を実装する

管理者の介入の必要性を回避するために証明書自動署名システムを実装する場合、いくつかのオプションがあります。 まず、Puppetマスターサーバーでこれを設定する必要があります。

Puppetマスターサーバー上の `+ puppet.conf `ファイルでは、ファイルの ` [master] `セクションの下に ` autosign +`オプションを設定できます。 これには、いくつかの異なる値を使用できます。

  • * + true + *:これは、Puppet masterサーバーに、チェックを行わずに、入ってくるすべての証明書リクエストに署名するように指示します。 これは実際の環境では非常に危険です。どのホストもCSRに署名してインフラストラクチャに入ることができるからです。

  • * + <whitelist_filename> + *:2番目のオプションは、ホストまたはホストの正規表現のホワイトリストとして機能するファイルを指定することです。 Puppetマスターは、このリストに対して証明書署名リクエストをチェックし、証明書に署名する必要があるかどうかを確認します。 証明書名は簡単になりすまされる可能性があるため、これもお勧めしません。

  • * + <policy_executable> + *:3番目のオプションは、証明書署名要求に署名する必要があるかどうかを判断するために実行できるスクリプトまたは実行可能ファイルを指定することです。 Puppetは証明書名を引数として渡し、CSR全体を標準入力を通じて渡します。 終了ステータス0が返された場合、証明書は署名されています。 別のステータスが与えられた場合、証明書は署名されません。

ポリシーベースの自動署名は、正当な要求と非正当な要求を区別する方法をarbitrarily意的に複雑にすることができるため、自動キー署名を実装する最も安全な方法です。

ポリシーベースの自動署名を示すために、インスタンスID変数「%i +」を含む「 cloud-config 」に「 certname 」変数を追加できます。 `%i。%f +`を使用して、選択したホスト名も含まれるようにします。

#cloud-config
puppet:
 conf:
   agent:
     server: "puppet."
     certname: "
 ca_cert: |

  . . .

完全な `+ cloud-config +`は次のようになります。

#cloud-config
puppet:
 conf:
   agent:
     server: "puppet."
     certname: ""
 ca_cert: |
   -----BEGIN CERTIFICATE-----
   MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
   ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
   GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC

   . . .

   arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
   rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
   l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
   UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
   -----END CERTIFICATE-----
output: {all: '| tee -a /var/log/cloud-init-output.log'}
runcmd:
 - while [ ! -e /usr/bin/puppet ]; do sleep 5; done; puppet agent --enable; service puppet restart
disable_ec2_metadata: true

Puppetマスターサーバーで、検証スクリプトを設定する必要があります。 RubyはすでにPuppet用にインストールされているため、簡単なRubyスクリプトを作成できます。

`+ certname `に `%i。%f `形式を使用しているため、 ` certname +`の最初の部分(最初のドットの前の部分)が有効なドロップレットIDに対応しているかどうかを確認できます。アカウント。 これは単なるチェックであり、実際にはホワイトリストファイル以上のことは行いません。 ただし、必要に応じて、このアイデアをはるかに複雑に適応させることができます。

これを行うには、DigitalOceanコントロールパネルの[アプリとAPI]セクションからの個人アクセストークンが必要です。 DigitalOcean Rubyライブラリのいずれかをインストールする必要もあります。 以下では、https://github.com/boats/barge [Barge]およびhttps://github.com/digitalocean/droplet_kit[DropletKit] DigitalOcean Rubyクライアントを使用するいくつかの簡略化されたスクリプトを示します。

割り込みクライアントを使用する場合は、次のように入力してPuppetマスターにgemをインストールします。

sudo gem install barge

次のスクリプトを使用して、証明書署名要求の「+ certname +」の最初の部分が有効なドロップレットIDに対応するかどうかを確認できます。

#!/usr/bin/env ruby

require 'barge'

TOKEN = ''

droplet_ids = []
certname = ARGV[0]
id_string = certname.slice(0...(certname.index('.')))
id_to_check = id_string.to_i

client = Barge::Client.new(access_token: TOKEN)
droplets = client.droplet.all

droplets.droplets.each do |droplet|
       droplet_ids << droplet.id
end

Kernel.exit(droplet_ids.include?(id_to_check))

代わりに、公式のDigitalOcean RubyクライアントであるDropletKitを使用する場合は、次のように入力してgemをインストールできます。

sudo gem install droplet_kit

DropletKit gemはRuby 2.0以上でのみ有効であるため、Puppetに同梱されているバージョンのRubyを使用する場合、これは可能性がないことに注意してください。

DropletKitのスクリプトは、次のように調整できます。

#!/usr/bin/env ruby

require 'droplet_kit'

TOKEN = ''

droplet_ids = []
certname = ARGV[0]
id_string = certname.slice(0...(certname.index('.')))
id_to_check = id_string.to_i

client = DropletKit::Client.new(access_token: TOKEN)
droplets = client.droplets.all

droplets.each do |droplet|
       droplet_ids << droplet.id
end

Kernel.exit(droplet_ids.include?(id_to_check))

インストールしたgemに対応するスクリプトを `+ / etc / puppet / validate.rb +`というファイルに配置し、次のように入力して実行可能としてマークできます。

sudo chmod +x /etc/puppet/validate.rb

その後、次のファイルを `+ puppet.conf `ファイル(Open Source Puppetを使用している場合は ` / etc / puppet / puppet.conf +`にあります)に追加できます。

. . .

[master]
autosign =

. . .

Apacheサービスを再起動して、新しい署名ポリシーを実装します。

sudo service apache2 restart

これで、Puppetマスターが証明書署名リクエストを受信すると、証明書名の最初の部分がアカウント内の有効なドロップレット名と一致するかどうかを確認します。 これは、実行可能ファイルを使用してリクエストを検証する方法の大まかな例です。

結論

`+ cloud-config +`スクリプトを活用することで、新しいサーバーを簡単にブートストラップし、既存の構成管理システムに引き渡すことができます。 これにより、管理ソリューションの範囲外で重要な変更を行う前に、既存のツールを使用してインフラストラクチャをすぐに制御できます。