PuppetとAWSクラウド形成による自動構成

画像 それで、料理本、レシピ、シェフのナイフを置いて、人形劇をしなければならなかった日が来ました。

そもそも、問題のステートメントは非常に些細なものです。開発者が環境を迅速かつ簡単に拡張できるように整理することです。 必須要件-自動構成にはPuppet Enterpriseを使用します

したがって、必要な環境について詳しく説明します。 これは2つのコンポーネントで構成されます。最初のコンポーネントはIISサーバーによって機能が実行されるフロントエンド、2番目のコンポーネントは実際に開発されたワーカーサービスとMongoDBデータベースを含むバックエンドです。 すでに理解されているように、両方のコンポーネントはWindows Serverに実装されます。 フロントエンドとワーカーサービスのコンテンツのソースはAWS S3から取得されます。AWSS3では、Jenkinsがすでに毎晩定期的にそれらを配置しています。



Cloud Fromationテンプレートの作成


2台のWindowsサーバーを起動するCloud Formationテンプレートを実装することは絶対に難しくありません。 これらのサーバーにどの構成を適用するかをPuppetに伝える方法を理解することは、はるかに興味深いことです。

Puppetの公式ドキュメントは、クライアントのホスト名に正規表現を適用することを提案していますが、これはAWS Amazonホスト名が自動的に発行され、インスタンスの停止後に変更される可能性があるため、私たちの場合は便利ではありません。マシンのホスト名を変更してから、puppetエージェントを起動してください。

ドキュメントをざっと見て、必要なもの- カスタム外部ファクト -を見つけました。 Chef Serverで作業する人にとって、事実は属性の類似物です。

ファクトをWindowsマシンに追加するには、次の内容のbatまたはps1ファイルを作成し、「 C:\ ProgramData \ PuppetLabs \ facter \ facts.d \」に配置する必要があります。

@echo off echo node_role=frontend echo app_version=Build1.2.0
      
      





serverRoleは、その名前が示すように、サーバーに割り当てられるロールです。buildNumberは、S3 AWSからダウンロードされるアプリケーションのバージョンです。

このファイルは、クラウド形成テンプレートによって作成されます。

DevEnv.tmpl
 { "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "Developers Stack", "Parameters" : { "KeyName" : { "Description" : "Key-pair name", "Type" : "String" }, "SuffixName" : { "Description" : "Suffix for all created resources", "Type" : "String" }, "FrontEndInstanceType" : { "Type" : "String", "Default" : "m1.small", "AllowedValues" : [ "m1.small", "m1.medium", "m1.large", "m1.xlarge"], "Description" : "EC2 instance type" }, "BackEndInstanceType" : { "Type" : "String", "Default" : "m1.small", "AllowedValues" : [ "m1.small", "m1.medium", "m1.large", "m1.xlarge"], "Description" : "EC2 instance type" }, "PuppetServer": { "Description" : "Puppet Server URL", "Type" : "String", "Default" : "ec2-231-231-123-123.us-west-2.compute.amazonaws.com" }, "Zone" : { "Type" : "CommaDelimitedList", "Description" : "The Availability Zone ", "Default" : "us-west-2c" }, "BuildVersion" : { "Type" : "String", "Description" : "Version of application build" }, "RoleName" : { "Type" : "String", "Description" : "Instance IAM role", "Default" : "WebInstance" }, "SecurityGroup" : { "Type" : "String", "Description" : "Default security group for stack", "Default" : "taws-security-group" } }, "Mappings" : { "WindowsInstanceType" : { "t1.micro" : { "Arch" : "64" }, "m1.small" : { "Arch" : "64" }, "m1.medium" : { "Arch" : "64" }, "m1.large" : { "Arch" : "64" }, "m1.xlarge" : { "Arch" : "64" } }, "WindowsRegionMap" : { "us-east-1" : { "AMI" : "ami-e55a7e8c" }, "us-west-2" : { "AMI" : "ami-1e53c82e" }, "us-west-1" : { "AMI" : "ami-b687b1f3" }, "eu-west-1" : { "AMI" : "ami-5f3ad728" }, "ap-southeast-1" : { "AMI" : "ami-96cd98c4" }, "ap-southeast-2" : { "AMI" : "ami-ab4a2daa" }, "ap-northeast-1" : { "AMI" : "ami-133fa329" }, "sa-east-1" : { "AMI" : "ami-bd3d9ba0" } } }, "Resources" : { "FrontEnd" : { "Type" : "AWS::EC2::Instance", "Properties" : { "KeyName" : { "Ref" : "KeyName" }, "ImageId" : { "Fn::FindInMap" : [ "WindowsRegionMap", { "Ref" : "AWS::Region" }, "AMI" ]}, "InstanceType" : { "Ref" : "FrontEndInstanceType" }, "IamInstanceProfile" : { "Ref" : "RoleName" }, "SecurityGroups" : [{ "Ref" : "SecurityGroup" }], "Tags" : [ {"Key" : "Name", "Value" : { "Fn::Join" : ["",[{"Ref" : "SuffixName"},"-DEV-FrontEnd"]]}} ], "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "<powershell>\n", "$MsiUrl = \"https://s3-us-west-2.amazonaws.com/mybucket/puppet.msi\"\n", "$downloadPath = \"c:\\puppet.msi\"\n", "$webClient = New-Object System.Net.WebClient\n", "$webClient.DownloadFile($MsiUrl, $downloadPath)\n", "$process = Start-Process -File $downloadPath -arg \"/qn /norestart\" -PassThru |wait-process\n", "$PublicHostName = Invoke-RestMethod -Uri http://169.254.169.254/latest/meta-data/public-hostname -Method Get\n", "Clear-Content 'C:\\ProgramData\\PuppetLabs\\puppet\\etc\\puppet.conf'\n", "Add-Content 'C:\\ProgramData\\PuppetLabs\\puppet\\etc\\puppet.conf' \"[main]\", \"runinterval=300\", \"certname=$PublicHostName\", \"server=",{ "Ref" : "PuppetServer" },"\", \"environment=",{ "Ref" : "PuppetEnvironment" },"\"\n", "Add-Content 'C:\\ProgramData\\PuppetLabs\\facter\\facts.d\\facts.bat' \"@echo off\", \"echo node_role=frontend\", \"echo app_version=",{ "Ref" : "BuildVersion" },"\"\n", "Restart-Service pe-puppet\n", "$MsiUrl = \"https://s3-us-west-2.amazonaws.com/mybucket/7zip.msi\"\n", "$downloadPath = \"c:\\7zip.msi\"\n", "$webClient = New-Object System.Net.WebClient\n", "$webClient.DownloadFile($MsiUrl, $downloadPath)\n", "$process = Start-Process -File $downloadPath -arg \"/qn \" -PassThru |wait-process\n", "</powershell>\n" ]]}} } }, "BackEnd" : { "Type" : "AWS::EC2::Instance", "Properties" : { "KeyName" : { "Ref" : "KeyName" }, "ImageId" : { "Fn::FindInMap" : [ "WindowsRegionMap", { "Ref" : "AWS::Region" }, "AMI" ]}, "InstanceType" : { "Ref" : "BackEndInstanceType" }, "IamInstanceProfile" : { "Ref" : "RoleName" }, "SecurityGroups" : [{ "Ref" : "SecurityGroup" }], "Tags" : [ {"Key" : "Name", "Value" : { "Fn::Join" : ["",[{"Ref" : "SuffixName"},"-DEV-BackEnd"]]}} ], "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "<powershell>\n", "$MsiUrl = \"https://s3-us-west-2.amazonaws.com/mybucket/puppet.msi\"\n", "$downloadPath = \"c:\\puppet.msi\"\n", "$webClient = New-Object System.Net.WebClient\n", "$webClient.DownloadFile($MsiUrl, $downloadPath)\n", "$process = Start-Process -File $downloadPath -arg \"/qn /norestart\" -PassThru |wait-process\n", "$PublicHostName = Invoke-RestMethod -Uri http://169.254.169.254/latest/meta-data/public-hostname -Method Get\n", "Clear-Content 'C:\\ProgramData\\PuppetLabs\\puppet\\etc\\puppet.conf'\n", "Add-Content 'C:\\ProgramData\\PuppetLabs\\puppet\\etc\\puppet.conf' \"[main]\", \"runinterval=300\", \"certname=$PublicHostName\", \"server=",{ "Ref" : "PuppetServer" },"\", \"environment=",{ "Ref" : "PuppetEnvironment" },"\"\n", "Add-Content 'C:\\ProgramData\\PuppetLabs\\facter\\facts.d\\facts.bat' \"@echo off\", \"echo node_role=backend\", \"echo app_version=",{ "Ref" : "BuildVersion" },"\"\n", "Restart-Service pe-puppet\n", "$MsiUrl = \"https://s3-us-west-2.amazonaws.com/mybucket/7zip.msi\"\n", "$downloadPath = \"c:\\7zip.msi\"\n", "$webClient = New-Object System.Net.WebClient\n", "$webClient.DownloadFile($MsiUrl, $downloadPath)\n", "$process = Start-Process -File $downloadPath -arg \"/qn \" -PassThru |wait-process\n", "</powershell>\n" ]]}} } } }, "Outputs" : { "FrontEndPublicDnsName" : { "Description" : "Public IP address of FrontEnd", "Value" : { "Fn::Join" : ["",[{ "Fn::GetAtt" : [ "FrontEnd", "PublicDnsName" ] }]]} }, "BackEndPublicDnsName" : { "Description" : "Public IP address of BackEnd", "Value" : { "Fn::Join" : ["",[{ "Fn::GetAtt" : [ "BackEnd", "PublicDnsName" ]}]]} } } }
      
      







テンプレートで使用されるパラメーター:



IAMロールとセキュリティグループは同じテンプレートで作成できますが、さらに正確になります。 私の例では、理解を簡単にするためにこれを行っていません。

UserDataセクションのpuppetエージェントでは、7zipがダウンロードおよびインストールされ、puppet.confおよびfacts.batが生成されます。

クラウド形成が完了したら、Puppetのセットアップに移りましょう。



Puppet Server Enterpriseの構成


Puppet Server Enterpriseをインストールするには、 インストーラーアーカイブをダウンロードし、解凍してpuppet-server-installerを実行するだけです。 サーバーでクライアントの自動登録を有効にするには次の内容のファイル/etc/puppetlabs/puppet/autosign.confを作成する必要があります。

 *
      
      





必要なモジュールを作成します。 モジュールは、Chefの料理本のようなものです。 それらは/ etc / puppetlabs / puppet / modulesフォルダーにあります。

簡素化されたモジュール構造:



まず、PuppetLabsから必要なモジュールを追加して、IISと管理をインストールします。

 puppet module install dism puppet module install opentable-iis
      
      





次に、opentable-iisのマニフェストを少し調整する必要があります

/etc/puppetlabs/puppet/modules/nodes/manifests/init.pp
クラスiis {

iis :: manage_app_pool {"$ {fqdn}":

enable_32_bit => true、

managed_runtime_version => 'v4.0'、

}->



iis :: manage_site {"$ {fqdn}":

site_path => 'C:\ MyAppPath'、

ポート=> '80'、

ip_address => '*'、

host_header => "$ {fqdn}"、

app_pool => "$ {fqdn}"

}



}



私は7つのモジュールを手に入れました(それらの数はさらに増えるでしょう。

  1. nodes - node_roleの値に基づいて、次に必要なモジュールを接続するモジュール

    /etc/puppetlabs/puppet/modules/nodes/manifests/init.pp
    クラスノード{

    if "$ {node_role}" == "backend" {

    バックエンドを含める

    }

    if "$ {node_role}" == "frontend" {

    フロントエンドを含める

    }

    }



  2. getbuild-このモジュールは、AWS S3からアプリケーションアーカイブをダウンロードして解凍するために必要です。

    /etc/puppetlabs/puppet/modules/getbuild/manifests/init.pp
    クラスgetbuild {

    ファイル{'c:\ config':

    確認=> 'ディレクトリ'

    }->

    ファイル{'c:\ Build':

    確認=> 'ディレクトリ'

    }->

    exec {'download_build':

    => "c:\\ config \\ $ {app_version}"を作成します。

    パス=> $ ::パス、

    command => "powershell.exe -executionpolicy unrestricted start-bitstransfer -source s3-us-west-2.amazonaws.com/mybucket $ {app_version} -Destination 'c:\\ config \\'"、

    }->

    exec {'app_install':

    => "c:\\ Build \ CustomBackendService.exe.config"を作成します。

    command => "\" c:\\ Program Files \\ 7-Zip \\ 7z.exe \ "xc:\\ config \\ $ {app_version} -oC:\\ Build"、

    }



    }



  3. mongodb -MongoDBをインストールするためのモジュール

    /etc/puppetlabs/puppet/modules/mongodb/manifests/init.pp
    クラスmongodb {

    ファイル{'c:/ config':

    確認=>ディレクトリ、

    }->

    ファイル{'c:/config/mongodb.zip':

    確認=>ファイル、

    モード=> '0777'、

    source => 'puppet:///modules/mongodb/mongodb-win32-x86_64-v2.4-latest.zip'、

    }->

    ファイル{'c:/ MongoDB':

    確認=>ディレクトリ、

    }->

    ファイル{'c:/ MongoDB / bin':

    確認=>ディレクトリ、

    }->

    ファイル{'c:/ MongoDB / Data':

    確認=>ディレクトリ、

    }->

    ファイル{'c:/ MongoDB / logs':

    確認=>ディレクトリ、

    }->

    exec {'mongodb-unzip':

    => 'c:/MongoDB/bin/mongod.exe'を作成し、

    command => '"c:\\ Program Files \\ 7-Zip \\ 7z.exe" ec:\\ config \ mongodb.zip -oC:\\ MongoDB \\ bin'、

    }->

    exec {'mongodb-install':

    => 'c:/MongoDB/logs/mongodb.log'を作成します。

    command => '"c:\\ MongoDB \\ mongod.exe" --dbpath = c:\\ MongoDB \\ Data --port 27017 --logpath = c:\\ MongoDB \ logs \\ mongodb.log- install --serviceName mongodb --serviceDisplayName "MongoDB Server" --serviceDescription "MongoDB Server" '、

    }->

    exec {'mongodb-run':

    パス=> $ ::パス、

    コマンド=> 'powershell.exe start-service mongodb'

    }

    }



  4. api-フロントエンドにアプリケーションをインストールするためのモジュール

    /etc/puppetlabs/puppet/modules/api/manifests/init.pp
    クラスAPI {



    getbuildを含める



    dism {'IIS-WebServerRole':

    確認=>存在、

    }->



    dism {'IIS-WebServer':

    確認=>存在、

    require => Dism ['IIS-WebServerRole']、

    }



    }



  5. worker-バックエンドにアプリケーションをインストールするためのモジュール

    /etc/puppetlabs/puppet/modules/worker/manifests/init.pp
    クラスワーカー{

    getbuildを含める

    exec {'service_install':

    => "c:\\ Build \\ Custom.AWS.BackendService.InstallLog"を作成します。

    command => "c:\\ Build \\ Custom.AWS.BackendService.exe -install"、

    }->

    exec {'service-run':

    パス=> $ ::パス、

    コマンド=> 'powershell.exe start-service Custom.AWS.Backend'

    }

    }



  6. フロントエンド - フロントエンドが機能するために必要なすべてのモジュールを接続するモジュール

    /etc/puppetlabs/puppet/modules/frontend/manifests/init.pp
    クラスフロントエンド{

    APIを含める

    iisを含める

    }



  7. バックエンド - バックエンドが機能するために必要なすべてのモジュールを接続するモジュール

    /etc/puppetlabs/puppet/modules/backend/manifests/init.pp
    クラスバックエンド{

    mongodbを含める

    労働者を含める

    }







マニフェストでは、ほぼすべての場所でexecリソースを使用しました。 作成オプションが正しく選択されている場合、このリソースはスムーズに実行されます。

一例の詳細:

 exec { 'mongodb-unzip': creates => 'c:/MongoDB/bin/mongod.exe', command => '"c:\\Program Files\\7-Zip\\7z.exe" ec:\\config\mongodb.zip -oC:\\MongoDB\\bin', }
      
      





実行可能ファイルc:/MongoDB/bin/mongod.exeがない場合、アーカイブは解凍されます。



便宜上、 Jenkinsなどのお気に入りのCIシステムにタスクを作成し、そこにCloud Formationテンプレートを起動するスクリプトを配置すると、開発者はワンクリックで環境を展開できます。



それだけです このガイドが役立つことを願っています...

この記事を読んでいる人たちの中にPuppetの使用に関する専門家がいるなら、私はあなたの意見を聞いてとても感謝します。



All Articles