{"id":8962,"date":"2015-04-17T14:00:07","date_gmt":"2015-04-17T05:00:07","guid":{"rendered":"http:\/\/www.creationline.com\/?p=8962"},"modified":"2023-08-29T14:02:09","modified_gmt":"2023-08-29T05:02:09","slug":"english-translation-lets-begin-infrastructure-as-code-with-knife-zero-getchef","status":"publish","type":"post","link":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962","title":{"rendered":"[English Translation] Let&#8217;s begin Infrastructure as Code with Knife-Zero #getchef"},"content":{"rendered":"<p>This is the English translation of <a href=\"\/lab\/6718\">Knife-Zero\u3067Infrastructure as Code\u3092\u59cb\u3081\u3088\u3046<\/a> (2014\/12\/24).<\/p>\n<h2>\u25a0<a href=\"#what-is-chef\" name=\"what-is-chef\">What is Chef?<\/a><\/h2>\n<p><a href=\"https:\/\/www.chef.io\/\">Chef<\/a> is a tool for centralized management of IT infrastructure information. Chef is described as follows in \"<a href=\"https:\/\/docs.chef.io\/chef_overview.html\">An Overview of Chef<\/a>\":<\/p>\n<blockquote><p>Chef is a powerful automation platform that transforms complex infrastructure into code, bringing your servers and services to life. (snip)<\/p>\n<p>Chef is built around simple concepts: achieving desired state, centralized modeling of IT infrastructure, and resource primitives that serve as building blocks. (snip)<\/p><\/blockquote>\n<p>The real value of Chef is: enables centralized management of IT infrastructure information, separates each component of the infrastructure into more detailed part so that they can be reused, and then converges those components to desired state.<\/p>\n<p>One of the great features of Chef, which is enabling centralized management of IT infrastructure information, tends to be overlooked in many cases. Chef can be used simply as an automated setup tool, too. However, it would be a waste not to utilize this great feature.<\/p>\n<h2>\u25a0<a href=\"#install-chef\" name=\"install-chef\">Installing Chef<\/a><\/h2>\n<p>Now, let's try to install Chef. You don't need Chef Server this time. We will use Ubuntu 12.04 LTS as a workstation and install only the client package.<br \/>\nWe will also use Ubuntu 12.04 LTS as a remote node to be managed.<\/p>\n<h3>\u25cf<a href=\"#install-chef-dk\" name=\"install-chef-dk\">Installing Chef Development Kit<\/a><\/h3>\n<p>The client package for workstation is <a href=\"http:\/\/docs.chef.io\/devkit\/\">Chef Development Kit<\/a>, commonly called \"<strong>Chef DK<\/strong>\". It contains not only the Chef client program, but also tools necessary to do development works with Chef, and Ruby that is required to operate Chef. This means <strong>you do not need to either install Ruby separately, or use RubyGems to install Chef<\/strong>.<\/p>\n<p>Chef DK is available for download from <a href=\"http:\/\/downloads.chef.io\/chef-dk\/\">Chef Development Kit | Chef Downloads | Chef<\/a>. Select OS, Chef DK version and OS version that suit your environment. This time, we have downloaded <strong>chefdk_0.3.5-1_amd64.deb<\/strong>. Let's install it now.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~$ sudo dpkg -i chefdk_0.3.5-1_amd64.deb<br \/>\nSelecting previously unselected package chefdk.<br \/>\n(Reading database ... 49102 files and directories currently installed.)<br \/>\nPreparing to unpack chefdk_0.3.5-1_amd64.deb ...<br \/>\nUnpacking chefdk (0.3.5-1) ...<br \/>\nSetting up chefdk (0.3.5-1) ...<br \/>\nThank you for installing Chef Development Kit!<br \/>\nubuntu@ws:~$<br \/>\n<\/code><\/p>\n<h3>\u25cf<a href=\"#install-knife-zero\" name=\"install-knife-zero\">Installing Knife-Zero<\/a><\/h3>\n<p>Use <a href=\"https:\/\/github.com\/higanworks\/knife-zero\">Knife-Zero<\/a>, we will not use the Chef Client program that comes with Chef DK here.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~$ chef gem install knife-zero --no-document<br \/>\nFetching: knife-zero-1.1.0.gem (100%)<br \/>\nWARNING:  You don't have \/home\/ubuntu\/.chefdk\/gem\/ruby\/2.1.0\/bin in your PATH,<br \/>\ngem executables will not run.<br \/>\nSuccessfully installed knife-zero-1.1.0<br \/>\n1 gem installed<br \/>\nubuntu@ws:~$<br \/>\n<\/code><\/p>\n<p>Warning here is not related to Knife-Zero, so you can ignore it.<\/p>\n<h3>\u25cf<a href=\"#generate-ssh-keypair\" name=\"generate-ssh-keypair\">Preparations: Creating SSH key pair<\/a><\/h3>\n<p>Since Knife-Zero uses SSH to operate the remote node, create an SSH private\/public key pair in advance. Here, we generate a key pair without a passphrase.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~$ ssh-keygen -N ''<br \/>\nGenerating public\/private rsa key pair.<br \/>\nEnter file in which to save the key (\/home\/ubuntu\/.ssh\/id_rsa):<br \/>\nCreated directory '\/home\/ubuntu\/.ssh'.<br \/>\nYour identification has been saved in \/home\/ubuntu\/.ssh\/id_rsa.<br \/>\nYour public key has been saved in \/home\/ubuntu\/.ssh\/id_rsa.pub.<br \/>\nThe key fingerprint is:<br \/>\n9a:72:67:23:3a:5c:2e:e9:74:03:44:0f:5e:87:0e:67 ubuntu@ws.example.jp<br \/>\nThe key's randomart image is:<br \/>\n+--[ RSA 2048]----+<br \/>\n|    o ...        |<br \/>\n|   o.+E.         |<br \/>\n|    o=.          |<br \/>\n|   .  .          |<br \/>\n|    .   S        |<br \/>\n|     ..o         |<br \/>\n|   .o+B +        |<br \/>\n|   .==.= .       |<br \/>\n|   .oo           |<br \/>\n+-----------------+<br \/>\nubuntu@ws:~$<br \/>\n<\/code><\/p>\n<p>As you may know, the SSH daemon must run on the target remote node, so start the node beforehand. Also, place the public key created in the previous step on the remote node.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@node:~$ mkdir .ssh<br \/>\nubuntu@node:~$ cat &gt; .ssh\/authorized_keys<br \/>\nssh-rsa (snip) ubuntu@ws.example.jp<br \/>\nubuntu@node:~$<br \/>\n<\/code><\/p>\n<p>For convenience, set the login account in such a way that enables to execute sudo without password to acquire a root privilege.<\/p>\n<h2>\u25a0<a href=\"#generate-chef-repo\" name=\"generate-chef-repo\">Creating a working environment<\/a><\/h2>\n<p>Create a directory tree to be used as an environment to execute Knife-Zero, and then place it under the management of git. This directory tree is called <a href=\"http:\/\/docs.chef.io\/chef_repo.html\">chef-repo<\/a> and this is where the infrastructure information is transformed into code (Infrastructure as Code).<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~$ chef generate repo chef-repo<br \/>\nCompiling Cookbooks...<br \/>\nRecipe: code_generator::repo<br \/>\n* directory[\/home\/ubuntu\/chef-repo] action create<br \/>\n- create new directory \/home\/ubuntu\/chef-repo<br \/>\n:<br \/>\n(diff output suppressed by config)<br \/>\nubuntu@ws:~$<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>ubuntu@ws:~$ cd chef-repo<br \/>\nubuntu@ws:~\/chef-repo$ tree<br \/>\n.<br \/>\n\u251c\u2500\u2500 LICENSE<br \/>\n\u251c\u2500\u2500 README.md<br \/>\n\u251c\u2500\u2500 Rakefile<br \/>\n\u251c\u2500\u2500 certificates<br \/>\n\u2502 \u2514\u2500\u2500 README.md<br \/>\n\u251c\u2500\u2500 chefignore<br \/>\n\u251c\u2500\u2500 config<br \/>\n\u2502 \u2514\u2500\u2500 rake.rb<br \/>\n\u251c\u2500\u2500 cookbooks<br \/>\n\u2502 \u2514\u2500\u2500 README.md<br \/>\n\u251c\u2500\u2500 data_bags<br \/>\n\u2502 \u2514\u2500\u2500 README.md<br \/>\n\u251c\u2500\u2500 environments<br \/>\n\u2502 \u2514\u2500\u2500 README.md<br \/>\n\u2514\u2500\u2500 roles<br \/>\n\u2514\u2500\u2500 README.md<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>6 directories, 10 files<br \/>\nubuntu@ws:~\/chef-repo$<\/p>\n<p><code lang=\"bash\"><br \/>\n<\/code><\/p>\n<p><code lang=\"bash\">ubuntu@ws:~\/chef-repo$ git init<br \/>\nInitialized empty Git repository in \/home\/ubuntu\/chef-repo\/.git\/<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p>Prepare the config file, which will be managed by Knife-Zero from now on.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ mkdir .chef<br \/>\nubuntu@ws:~\/chef-repo$ echo 'local_mode true' &gt; .chef\/knife.rb<br \/>\nubuntu@ws:~\/chef-repo$ cat .chef\/knife.rb<br \/>\nlocal_mode true<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<h2>\u25a0<a href=\"#install-chef-client\" name=\"install-chef-client\">Installing Chef-Client to Node<\/a><\/h2>\n<p>Install Chef-Client on the remote node to be managed by Chef.<br \/>\nUse \"<strong>knife zero bootstrap<\/strong>\" command for installation. \"<strong>node.example.jp<\/strong>\" specifies a node's host name, \"<strong>-x ubuntu<\/strong>\" specifies a login user name, and \"<strong>--sudo<\/strong>\" enables to execute sudo command for getting a root privilege.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero bootstrap node.example.jp -x ubuntu --sudo<br \/>\nConnecting to node.example.jp<br \/>\nnode.example.jp Installing Chef Client...<br \/>\nnode.example.jp --2014-12-19 12:06:20--  https:\/\/www.opscode.com\/chef\/install.sh<br \/>\nnode.example.jp Resolving www.opscode.com (www.opscode.com)... 184.106.28.90<br \/>\nnode.example.jp Connecting to www.opscode.com (www.opscode.com)|184.106.28.90|:443... connected.<br \/>\nnode.example.jp HTTP request sent, awaiting response... 200 OK<br \/>\nnode.example.jp Length: 18285 (18K) [application\/x-sh]<br \/>\nnode.example.jp Saving to: `STDOUT'<br \/>\nnode.example.jp<br \/>\n100%[======================================&gt;] 18,285      --.-K\/s   in 0.002s<br \/>\nnode.example.jp<br \/>\nnode.example.jp 2014-12-19 12:06:21 (7.52 MB\/s) - stdout saved [18285\/18285]<br \/>\nnode.example.jp<br \/>\nnode.example.jp Downloading Chef 11 for ubuntu...<br \/>\nnode.example.jp downloading https:\/\/www.opscode.com\/chef\/metadata?v=11&amp;prerelease=false&amp;nightlies=false&amp;p=ubuntu&amp;pv=12.04&amp;m=x86_64<br \/>\nnode.example.jp   to file \/tmp\/install.sh.1100\/metadata.txt<br \/>\nnode.example.jp trying wget...<br \/>\nnode.example.jp url https:\/\/opscode-omnibus-packages.s3.amazonaws.com\/ubuntu\/12.04\/x86_64\/chef_11.16.4-1_amd64.deb<br \/>\nnode.example.jp md5 2ffff5b4d80e4dcffc917f8eb2003a31<br \/>\nnode.example.jp sha256  28b08975e7e33ac46c888616ec7fa232a0c624aeeda81e58a6047d2c6b62edfb<br \/>\nnode.example.jp downloaded metadata file looks valid...<br \/>\nnode.example.jp downloading https:\/\/opscode-omnibus-packages.s3.amazonaws.com\/ubuntu\/12.04\/x86_64\/chef_11.16.4-1_amd64.deb<br \/>\nnode.example.jp   to file \/tmp\/install.sh.1100\/chef_11.16.4-1_amd64.deb<br \/>\nnode.example.jp trying wget...<br \/>\nnode.example.jp Comparing checksum with sha256sum...<br \/>\nnode.example.jp Installing Chef 11<br \/>\nnode.example.jp installing with dpkg...<br \/>\nnode.example.jp Selecting previously unselected package chef.<br \/>\n(Reading database ... 49102 files and directories currently installed.)<br \/>\nnode.example.jp Preparing to unpack ...\/chef_11.16.4-1_amd64.deb ...<br \/>\nnode.example.jp Setting up chef (11.16.4-1) ...<br \/>\nnode.example.jp Thank you for installing Chef!<br \/>\nnode.example.jp Starting first Chef Client run...<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp Creating a new client identity for node.example.jp using the validator key.<br \/>\nnode.example.jp resolving cookbooks for run list: []<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp [2014-12-19T12:06:48+09:00] WARN: Node node.example.jp has an empty run list.<br \/>\nnode.example.jp Converging 0 resources<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 0\/0 resources updated in 1.443860973 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p>Chef-Client is automatically downloaded and installed on the node.<br \/>\nThe node is now under the management of Chef. The data to be managed is stored in the Chef-Repo directory of the workstation, not in Chef Server.<\/p>\n<p><code lang=\"javascript\"><br \/>\nubuntu@ws:~\/chef-repo$ cat clients\/node.example.jp.json | cat<br \/>\n{<br \/>\n\"name\": \"node.example.jp\",<br \/>\n\"public_key\": \"-----BEGIN PUBLIC KEY-----\\n(snip)\\n-----END PUBLIC KEY-----\\n\"<br \/>\n}<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"javascript\"><br \/>\nubuntu@ws:~\/chef-repo$ cat nodes\/node.example.jp.json<br \/>\n{<br \/>\n\"name\": \"node.example.jp\",<br \/>\n\"normal\": {<br \/>\n\"tags\": [<\/code><\/p>\n<p><code lang=\"javascript\"><code lang=\"javascript\"><\/code><\/code><\/p>\n<p>]<br \/>\n},<br \/>\n\"automatic\": {<br \/>\n\"network\": {<br \/>\n\"interfaces\": {<br \/>\n\"lo\": {<br \/>\n\"mtu\": \"16436\",<br \/>\n\"flags\": [<br \/>\n\"LOOPBACK\",<br \/>\n\"UP\",<br \/>\n\"LOWER_UP\"<br \/>\n],<br \/>\n\"encapsulation\": \"Loopback\",<br \/>\n\"addresses\": {<br \/>\n\"127.0.0.1\": {<br \/>\n\"family\": \"inet\",<br \/>\n\"prefixlen\": \"8\",<br \/>\n\"netmask\": \"255.0.0.0\",<br \/>\n\"scope\": \"Node\"<br \/>\n},<br \/>\n\"::1\": {<br \/>\n\"family\": \"inet6\",<br \/>\n\"prefixlen\": \"128\",<br \/>\n\"scope\": \"Node\"<br \/>\n}<br \/>\n},<br \/>\n\"state\": \"unknown\"<br \/>\n},<br \/>\n\"eth0\": {<br \/>\n\"type\": \"eth\",<br \/>\n\"number\": \"0\",<br \/>\n\"mtu\": \"1500\",<br \/>\n\"flags\": [<br \/>\n\"BROADCAST\",<br \/>\n\"MULTICAST\",<br \/>\n\"UP\",<br \/>\n\"LOWER_UP\"<br \/>\n],<br \/>\n\"encapsulation\": \"Ethernet\",<br \/>\n\"addresses\": {<br \/>\n\"52:54:00:8E:F7:2A\": {<br \/>\n\"family\": \"lladdr\"<br \/>\n},<br \/>\n\"192.168.122.67\": {<br \/>\n\"family\": \"inet\",<br \/>\n\"prefixlen\": \"24\",<br \/>\n\"netmask\": \"255.255.255.0\",<br \/>\n\"broadcast\": \"192.168.122.255\",<br \/>\n\"scope\": \"Global\"<br \/>\n},<br \/>\n\"fe80::5054:ff:fe8e:f72a\": {<br \/>\n\"family\": \"inet6\",<br \/>\n\"prefixlen\": \"64\",<br \/>\n\"scope\": \"Link\"<br \/>\n}<br \/>\n},<br \/>\n\"state\": \"up\",<br \/>\n\"arp\": {<br \/>\n\"192.168.122.209\": \"52:54:00:62:c3:07\"<br \/>\n},<br \/>\n:<br \/>\n\"recipes\": [<\/p>\n<p><code lang=\"javascript\"><code lang=\"javascript\"><\/code><\/code><\/p>\n<p>],<br \/>\n\"roles\": [<\/p>\n<p><code lang=\"javascript\"><br \/>\n<\/code><\/p>\n<p><code lang=\"javascript\">    ]<br \/>\n}<br \/>\n}<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p>Let's use this opportunity to register the workstation itself.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero bootstrap ws.example.jp -x ubuntu --sudo<br \/>\nConnecting to ws.example.jp<br \/>\nws.example.jp Starting first Chef Client run...<br \/>\n:<br \/>\nws.example.jp Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp Creating a new client identity for ws.example.jp using the validator key.<br \/>\nws.example.jp resolving cookbooks for run list: []<br \/>\nws.example.jp Synchronizing Cookbooks:<br \/>\nws.example.jp Compiling Cookbooks...<br \/>\nws.example.jp [2014-12-19T12:33:12+09:00] WARN: Node ws.example.jp has an empty run list.<br \/>\nws.example.jp Converging 0 resources<br \/>\nws.example.jp<br \/>\nws.example.jp Running handlers:<br \/>\nws.example.jp Running handlers complete<br \/>\nws.example.jp Chef Client finished, 0\/0 resources updated in 1.627046827 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ ls -l clients<br \/>\ntotal 8<br \/>\n-rw-rw-r-- 1 ubuntu ubuntu 511 12\u6708 19 12:06 node.example.jp.json<br \/>\n-rw-rw-r-- 1 ubuntu ubuntu 509 12\u6708 19 12:33 ws.example.jp.json<br \/>\nubuntu@ws:~\/chef-repo$ ls -l nodes<br \/>\ntotal 64<br \/>\n-rw-rw-r-- 1 ubuntu ubuntu 31169 12\u6708 19 12:23 node.example.jp.json<br \/>\n-rw-rw-r-- 1 ubuntu ubuntu 31157 12\u6708 19 12:33 ws.example.jp.json<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p>Manage nodes using Knife-Zero from now on.<\/p>\n<h2>\u25a0<a href=\"#manage-by-knife\" name=\"manage-by-knife\">Managing nodes with knife command<\/a><\/h2>\n<p>We will now try to get the information registered by using knife command. We use <a href=\"http:\/\/docs.chef.io\/knife_search.html\">knife search<\/a> here. The example below shows acquiring an IP address of a node.<\/p>\n<p><code lang=\"yaml\"><br \/>\nubuntu@ws:~\/chef-repo$ knife search 'name:*' --attribute ipaddress<br \/>\n2 items found<\/code><\/p>\n<p><code lang=\"yaml\"><code lang=\"yaml\"><\/code><\/code><\/p>\n<p>node.example.jp:<br \/>\nipaddress: 192.168.122.67<\/p>\n<p><code lang=\"yaml\"><code lang=\"yaml\"><\/code><\/code><\/p>\n<p>ws.example.jp:<br \/>\nipaddress: 192.168.122.209<\/p>\n<p><code lang=\"yaml\"><br \/>\n<\/code><\/p>\n<p><code lang=\"yaml\">ubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p>These are coming from the data stored in Chef-Repo.<br \/>\nInformation about each node can be displayed by using argument.<\/p>\n<p><code lang=\"yaml\"><br \/>\nubuntu@ws:~\/chef-repo$ knife search 'name:node*' --attribute fqdn<br \/>\n1 items found<\/code><\/p>\n<p><code lang=\"yaml\"><code lang=\"yaml\"><\/code><\/code><\/p>\n<p>node.example.jp:<br \/>\nfqdn: node.example.jp<\/p>\n<p><code lang=\"yaml\"><code lang=\"yaml\"><\/code><\/code><\/p>\n<p>ubuntu@ws:~\/chef-repo$ knife search 'name:ws*' --attribute fqdn<br \/>\n1 items found<\/p>\n<p><code lang=\"yaml\"><code lang=\"yaml\"><\/code><\/code><\/p>\n<p>ws.example.jp:<br \/>\nfqdn: ws.example.jp<\/p>\n<p><code lang=\"yaml\"><br \/>\n<\/code><\/p>\n<p><code lang=\"yaml\">ubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><a href=\"http:\/\/docs.chef.io\/knife_ssh.html\">knife ssh<\/a> allows you to execute commands remotely on each node.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife ssh 'name:*' 'uname -a'<br \/>\nnode.example.jp Linux node.example.jp 3.2.0-74-generic #109-Ubuntu SMP Tue Dec 9 16:45:49 UTC 2014 x86_64 x86_64 x86_64 GNU\/Linux<br \/>\nws.example.jp   Linux ws.example.jp 3.2.0-74-generic #109-Ubuntu SMP Tue Dec 9 16:45:49 UTC 2014 x86_64 x86_64 x86_64 GNU\/Linux<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<h2>\u25a0<a href=\"#create-cookbook\" name=\"create-cookbook\">Creating cookbooks<\/a><\/h2>\n<p>Chef files that enable infrastructure as code and describe the desired state are called <a href=\"http:\/\/docs.chef.io\/cookbooks.html\">Cookbook<\/a>. <strong>You can write a cookbook without knowing Ruby<\/strong>. Let's forget for a moment that cookbooks are internal DSL in Ruby. All we need to know is how to write a cookbook.<\/p>\n<h3>\u25cf<a href=\"#install-single-package\" name=\"install-single-package\">Installing one package<\/a><\/h3>\n<p>Let's create a cookbook to install an <strong>ntp<\/strong> package.<br \/>\nUse \"<strong>chef generate cookbook<\/strong>\" command to prepare a cookbook base structure. Name this cookbook as \"<strong>ntp<\/strong>\".<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ chef generate cookbook cookbooks\/ntp<br \/>\nCompiling Cookbooks...<br \/>\nRecipe: code_generator::cookbook<br \/>\n* directory[\/home\/ubuntu\/chef-repo\/cookbooks\/ntp] action create<br \/>\n- create new directory \/home\/ubuntu\/chef-repo\/cookbooks\/ntp<br \/>\n:<br \/>\n(diff output suppressed by config)<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ tree cookbooks\/ntp<br \/>\ncookbooks\/ntp<br \/>\n\u251c\u2500\u2500 Berksfile<br \/>\n\u251c\u2500\u2500 README.md<br \/>\n\u251c\u2500\u2500 chefignore<br \/>\n\u251c\u2500\u2500 metadata.rb<br \/>\n\u2514\u2500\u2500 recipes<br \/>\n\u2514\u2500\u2500 default.rb<\/code><\/p>\n<p><code lang=\"bash\"><br \/>\n<\/code><\/p>\n<p><code lang=\"bash\">1 directory, 5 files<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><strong>cookbooks\/ntp\/recipes\/default.rb<\/strong> is called \"default <a href=\"http:\/\/docs.chef.io\/recipes.html\">Recipe<\/a>\" of \"ntp cookbook\". Usually, cookbook is a collection of various types of data except for recipes. However, you could consider cookbooks and recipes roughly the same thing.<br \/>\nNow, let's edit the recipe and install the <strong>ntp<\/strong> package.<\/p>\n<p><code lang=\"ruby\"><br \/>\n#<br \/>\n# Cookbook Name:: ntp<br \/>\n# Recipe:: default<br \/>\n#<br \/>\n# Copyright (c) 2014 The Authors, All Rights Reserved.<\/code><\/p>\n<p><code lang=\"ruby\"><br \/>\n<\/code><\/p>\n<p><code lang=\"ruby\">package 'ntp'<br \/>\n<\/code><\/p>\n<p>It's as simple as this. Only one line has been added except the original comments. You can't find any Ruby element.<br \/>\nApply this recipe to the target node.<\/p>\n<p><code lang=\"yaml\"><br \/>\nubuntu@ws:~\/chef-repo$ knife node run_list add node.example.jp 'recipe[ntp]'<br \/>\nnode.example.jp:<br \/>\nrun_list: recipe[ntp]<br \/>\nubuntu@ws:~\/chef-repo$ knife node run_list add ws.example.jp 'recipe[ntp]'<br \/>\nws.example.jp:<br \/>\nrun_list: recipe[ntp]<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p>Before executing chef-client on the node and actually applying it, try why-run (similar to dry-run) with <strong>-W<\/strong> option.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero chef_client 'name:*' -x ubuntu --sudo -W<br \/>\nnode.example.jp [2014-12-22T13:09:25+09:00] WARN:<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp resolving cookbooks for run list: [\"ntp\"]<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp   - ntp<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp Converging 1 resources<br \/>\nnode.example.jp Recipe: ntp::default<br \/>\nnode.example.jp   * package[ntp] action install<br \/>\nnode.example.jp     - Would install version 1:4.2.6.p3+dfsg-1ubuntu3.1 of package ntp<br \/>\nnode.example.jp [2014-12-22T13:09:26+09:00] WARN: In whyrun mode, so NOT performing node save.<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 1\/1 resources would have been updated<br \/>\nws.example.jp   [2014-12-22T13:09:27+09:00] WARN:<br \/>\n:<br \/>\nws.example.jp   Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp   resolving cookbooks for run list: [\"ntp\"]<br \/>\nws.example.jp   Synchronizing Cookbooks:<br \/>\nws.example.jp     - ntp<br \/>\nws.example.jp   Compiling Cookbooks...<br \/>\nws.example.jp   Converging 1 resources<br \/>\nws.example.jp   Recipe: ntp::default<br \/>\nws.example.jp     * package[ntp] action install<br \/>\nws.example.jp       - Would install version 1:4.2.6.p3+dfsg-1ubuntu3.1 of package ntp<br \/>\nws.example.jp   [2014-12-22T13:09:28+09:00] WARN: In whyrun mode, so NOT performing node save.<br \/>\nws.example.jp<br \/>\nws.example.jp   Running handlers:<br \/>\nws.example.jp   Running handlers complete<br \/>\nws.example.jp   Chef Client finished, 1\/1 resources would have been updated<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p>You can see that the <strong>ntp<\/strong> package is being installed. Now, remove the -W option and apply recipe to converge the node to the desired state.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero chef_client 'name:*' -x ubuntu --sudo<br \/>\nnode.example.jp [2014-12-22T13:14:00+09:00] WARN:<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp resolving cookbooks for run list: [\"ntp\"]<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp   - ntp<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp Converging 1 resources<br \/>\nnode.example.jp Recipe: ntp::default<br \/>\nnode.example.jp   * package[ntp] action install<br \/>\nnode.example.jp     - install version 1:4.2.6.p3+dfsg-1ubuntu3.1 of package ntp<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 1\/1 resources updated in 9.409252235 seconds<br \/>\nws.example.jp   [2014-12-22T13:14:11+09:00] WARN:<br \/>\n:<br \/>\nws.example.jp   Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp   resolving cookbooks for run list: [\"ntp\"]<br \/>\nws.example.jp   Synchronizing Cookbooks:<br \/>\nws.example.jp     - ntp<br \/>\nws.example.jp   Compiling Cookbooks...<br \/>\nws.example.jp   Converging 1 resources<br \/>\nws.example.jp   Recipe: ntp::default<br \/>\nws.example.jp     * package[ntp] action install<br \/>\nws.example.jp       - install version 1:4.2.6.p3+dfsg-1ubuntu3.1 of package ntp<br \/>\nws.example.jp<br \/>\nws.example.jp   Running handlers:<br \/>\nws.example.jp   Running handlers complete<br \/>\nws.example.jp   Chef Client finished, 1\/1 resources updated in 10.834032539 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p>The recipe has been applied successfully. \"<strong>1\/1 resources updated<\/strong>\" indicates that there has been a change in one out of one resource of the node. Apply the recipe once again in order to check idempotency.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero chef_client 'name:*' -x ubuntu --sudo<br \/>\nnode.example.jp [2014-12-22T13:18:52+09:00] WARN:<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp resolving cookbooks for run list: [\"ntp\"]<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp   - ntp<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp Converging 1 resources<br \/>\nnode.example.jp Recipe: ntp::default<br \/>\nnode.example.jp   * package[ntp] action install (up to date)<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 0\/1 resources updated in 0.991954497 seconds<br \/>\nws.example.jp   [2014-12-22T13:18:55+09:00] WARN:<br \/>\n:<br \/>\nws.example.jp   Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp   resolving cookbooks for run list: [\"ntp\"]<br \/>\nws.example.jp   Synchronizing Cookbooks:<br \/>\nws.example.jp     - ntp<br \/>\nws.example.jp   Compiling Cookbooks...<br \/>\nws.example.jp   Converging 1 resources<br \/>\nws.example.jp   Recipe: ntp::default<br \/>\nws.example.jp     * package[ntp] action install (up to date)<br \/>\nws.example.jp<br \/>\nws.example.jp   Running handlers:<br \/>\nws.example.jp   Running handlers complete<br \/>\nws.example.jp   Chef Client finished, 0\/1 resources updated in 1.050684551 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p>\"<strong>0\/1 resources updated<\/strong>\" indicates that there has been no change in any resources of the node.<br \/>\nIn order to check idempotency, uninstall the package and run the recipe once again.<\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife ssh 'name:*' 'sudo apt-get purge -y ntp' -x ubuntu<br \/>\nReading package lists... Done<br \/>\nBuilding dependency tree<br \/>\nReading state information... Done<br \/>\nws.example.jp   The following packages were automatically installed and are no longer required:<br \/>\nws.example.jp     libopts25 libcap2<br \/>\nws.example.jp   Use 'apt-get autoremove' to remove them.<br \/>\nws.example.jp   The following packages will be REMOVED:<br \/>\nws.example.jp     ntp*<br \/>\nws.example.jp   0 upgraded, 0 newly installed, 1 to remove and 1 not upgraded.<br \/>\nws.example.jp   After this operation, 1,511 kB disk space will be freed.<br \/>\n(Reading database ... 100642 files and directories currently installed.)<br \/>\nws.example.jp   Removing ntp ...<br \/>\nws.example.jp    * Stopping NTP server ntpd                              [ OK ]<br \/>\nws.example.jp   Purging configuration files for ntp ...<br \/>\nws.example.jp   Processing triggers for man-db ...<br \/>\nws.example.jp   Processing triggers for ureadahead ...<br \/>\nReading package lists... Done<br \/>\nBuilding dependency tree<br \/>\nReading state information... Done<br \/>\nnode.example.jp The following packages were automatically installed and are no longer required:<br \/>\nnode.example.jp   libopts25 libcap2<br \/>\nnode.example.jp Use 'apt-get autoremove' to remove them.<br \/>\nnode.example.jp The following packages will be REMOVED:<br \/>\nnode.example.jp   ntp*<br \/>\nnode.example.jp 0 upgraded, 0 newly installed, 1 to remove and 1 not upgraded.<br \/>\nnode.example.jp After this operation, 1,511 kB disk space will be freed.<br \/>\n(Reading database ... 61224 files and directories currently installed.)<br \/>\nnode.example.jp Removing ntp ...<br \/>\nnode.example.jp  * Stopping NTP server ntpd                              [ OK ]<br \/>\nnode.example.jp Purging configuration files for ntp ...<br \/>\nnode.example.jp Processing triggers for man-db ...<br \/>\nnode.example.jp Processing triggers for ureadahead ...<br \/>\nubuntu@ws:~\/chef-repo$<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero chef_client 'name:*' -x ubuntu --sudo<br \/>\nnode.example.jp [2014-12-22T13:25:47+09:00] WARN:<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp resolving cookbooks for run list: [\"ntp\"]<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp   - ntp<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp Converging 1 resources<br \/>\nnode.example.jp Recipe: ntp::default<br \/>\nnode.example.jp   * package[ntp] action install<br \/>\nnode.example.jp     - install version 1:4.2.6.p3+dfsg-1ubuntu3.1 of package ntp<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 1\/1 resources updated in 5.015853954 seconds<br \/>\nws.example.jp   [2014-12-22T13:25:54+09:00] WARN:<br \/>\n:<br \/>\nws.example.jp   Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp   resolving cookbooks for run list: [\"ntp\"]<br \/>\nws.example.jp   Synchronizing Cookbooks:<br \/>\nws.example.jp     - ntp<br \/>\nws.example.jp   Compiling Cookbooks...<br \/>\nws.example.jp   Converging 1 resources<br \/>\nws.example.jp   Recipe: ntp::default<br \/>\nws.example.jp     * package[ntp] action install<br \/>\nws.example.jp       - install version 1:4.2.6.p3+dfsg-1ubuntu3.1 of package ntp<br \/>\nws.example.jp<br \/>\nws.example.jp   Running handlers:<br \/>\nws.example.jp   Running handlers complete<br \/>\nws.example.jp   Chef Client finished, 1\/1 resources updated in 5.624764122 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>\"<strong>1\/1 resources updated<\/strong>\" indicates that the recipe has been applied successfully again and the resource has been updated.<br \/>\nIn addition, information stored in <strong>nodes\/<\/strong> directory of Chef-Repo directory gets updated when something like Chef-Client is executed.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"diff\"><br \/>\nubuntu@ws:~\/chef-repo$ git diff<br \/>\ndiff --git a\/nodes\/node.example.jp.json b\/nodes\/node.example.jp.json<br \/>\nindex d90e315..03bea39 100644<br \/>\n--- a\/nodes\/node.example.jp.json<br \/>\n+++ b\/nodes\/node.example.jp.json<br \/>\n:<br \/>\n@@ -1207,11 +1208,11 @@<br \/>\n},<br \/>\n\"current_user\": \"ubuntu\",<br \/>\n\"root_group\": \"root\",<br \/>\n-    \"ohai_time\": 1418959381.048563,<br \/>\n-    \"uptime_seconds\": 2566,<br \/>\n-    \"uptime\": \"42 minutes 46 seconds\",<br \/>\n-    \"idletime_seconds\": 2528,<br \/>\n-    \"idletime\": \"42 minutes 08 seconds\",<br \/>\n+    \"ohai_time\": 1419222348.6213446,<br \/>\n+    \"uptime_seconds\": 5229,<br \/>\n+    \"uptime\": \"1 hours 27 minutes 09 seconds\",<br \/>\n+    \"idletime_seconds\": 5154,<br \/>\n+    \"idletime\": \"1 hours 25 minutes 54 seconds\",<br \/>\n\"block_device\": {<br \/>\n\"ram0\": {<br \/>\n\"size\": \"131072\",<br \/>\n@@ -1316,10 +1317,14 @@<br \/>\n}<br \/>\n},<br \/>\n\"recipes\": [<br \/>\n-<br \/>\n+      \"ntp\",<br \/>\n+      \"ntp::default\"<br \/>\n],<br \/>\n\"roles\": [<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"diff\"><\/code><\/code><\/code><\/p>\n<p>]<br \/>\n- }<br \/>\n+ },<br \/>\n+ \"run_list\": [<br \/>\n+ \"recipe[ntp]\"<br \/>\n+ ]<br \/>\n}<br \/>\ndiff --git a\/nodes\/ws.example.jp.json b\/nodes\/ws.example.jp.json<br \/>\nindex 09b10d6..099b1af 100644<br \/>\n--- a\/nodes\/ws.example.jp.json<br \/>\n+++ b\/nodes\/ws.example.jp.json<br \/>\n:<br \/>\n@@ -1207,11 +1208,11 @@<br \/>\n},<br \/>\n\"current_user\": \"ubuntu\",<br \/>\n\"root_group\": \"root\",<br \/>\n- \"ohai_time\": 1418959992.8692613,<br \/>\n- \"uptime_seconds\": 3175,<br \/>\n- \"uptime\": \"52 minutes 55 seconds\",<br \/>\n- \"idletime_seconds\": 3127,<br \/>\n- \"idletime\": \"52 minutes 07 seconds\",<br \/>\n+ \"ohai_time\": 1419222354.9337227,<br \/>\n+ \"uptime_seconds\": 5235,<br \/>\n+ \"uptime\": \"1 hours 27 minutes 15 seconds\",<br \/>\n+ \"idletime_seconds\": 5117,<br \/>\n+ \"idletime\": \"1 hours 25 minutes 17 seconds\",<br \/>\n\"block_device\": {<br \/>\n\"ram0\": {<br \/>\n\"size\": \"131072\",<br \/>\n@@ -1316,10 +1317,14 @@<br \/>\n}<br \/>\n},<br \/>\n\"recipes\": [<br \/>\n-<br \/>\n+ \"ntp\",<br \/>\n+ \"ntp::default\"<br \/>\n],<br \/>\n\"roles\": [<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"diff\"><br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"diff\">     ]<br \/>\n-  }<br \/>\n+  },<br \/>\n+  \"run_list\": [<br \/>\n+    \"recipe[ntp]\"<br \/>\n+  ]<br \/>\n}<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<h3>\u25cf<a href=\"#install-multi-packages\" name=\"install-multi-packages\">Installing multiple packages<\/a><\/h3>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Let's create a cookbook that installs the <strong>nginx<\/strong> and <strong>redis-server<\/strong> packages.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ chef generate cookbook cookbooks\/multi_pkgs<br \/>\nCompiling Cookbooks...<br \/>\nRecipe: code_generator::cookbook<br \/>\n* directory[\/home\/ubuntu\/chef-repo\/cookbooks\/multi_pkgs] action create<br \/>\n- create new directory \/home\/ubuntu\/chef-repo\/cookbooks\/multi_pkgs<br \/>\n:<br \/>\n(diff output suppressed by config)<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"ruby\"><br \/>\nubuntu@ws:~\/chef-repo$ vi cookbooks\/multi_pkgs\/recipes\/default.rb<br \/>\n#<br \/>\n# Cookbook Name:: multi_pkgs<br \/>\n# Recipe:: default<br \/>\n#<br \/>\n# Copyright (c) 2014 The Authors, All Rights Reserved.<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"ruby\"><br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"ruby\">package 'nginx'<br \/>\npackage 'redis-server'<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"yaml\"><br \/>\nubuntu@ws:~\/chef-repo$ knife node run_list add node.example.jp 'recipe[multi_pkgs]'<br \/>\nnode.example.jp:<br \/>\nrun_list:<br \/>\nrecipe[ntp]<br \/>\nrecipe[multi_pkgs]<br \/>\nubuntu@ws:~\/chef-repo$ knife node run_list add ws.example.jp 'recipe[multi_pkgs]'<br \/>\nws.example.jp:<br \/>\nrun_list:<br \/>\nrecipe[ntp]<br \/>\nrecipe[multi_pkgs]<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero chef_client 'name:*' -x ubuntu --sudo<br \/>\nnode.example.jp [2014-12-22T16:23:51+09:00] WARN:<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\"]<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp   - ntp<br \/>\nnode.example.jp   - multi_pkgs<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp Converging 3 resources<br \/>\nnode.example.jp Recipe: ntp::default<br \/>\nnode.example.jp   * package[ntp] action install (up to date)<br \/>\nnode.example.jp Recipe: multi_pkgs::default<br \/>\nnode.example.jp   * package[nginx] action install<br \/>\nnode.example.jp     - install version 1.1.19-1ubuntu0.6 of package nginx<br \/>\nnode.example.jp   * package[redis-server] action install<br \/>\nnode.example.jp     - install version 2:2.2.12-1build1 of package redis-server<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 2\/3 resources updated in 14.823459658 seconds<br \/>\nws.example.jp   [2014-12-22T16:24:07+09:00] WARN:<br \/>\n:<br \/>\nws.example.jp   Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp   resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\"]<br \/>\nws.example.jp   Synchronizing Cookbooks:<br \/>\nws.example.jp     - ntp<br \/>\nws.example.jp     - multi_pkgs<br \/>\nws.example.jp   Compiling Cookbooks...<br \/>\nws.example.jp   Converging 3 resources<br \/>\nws.example.jp   Recipe: ntp::default<br \/>\nws.example.jp     * package[ntp] action install (up to date)<br \/>\nws.example.jp   Recipe: multi_pkgs::default<br \/>\nws.example.jp     * package[nginx] action install<br \/>\nws.example.jp       - install version 1.1.19-1ubuntu0.6 of package nginx<br \/>\nws.example.jp     * package[redis-server] action install<br \/>\nws.example.jp       - install version 2:2.2.12-1build1 of package redis-server<br \/>\nws.example.jp<br \/>\nws.example.jp   Running handlers:<br \/>\nws.example.jp   Running handlers complete<br \/>\nws.example.jp   Chef Client finished, 2\/3 resources updated in 15.721211671 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Installation has been completed. Uninstall the packages for now.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife ssh 'name:*' 'sudo apt-get purge -y nginx redis-server' -x ubuntu<br \/>\nReading package lists... Done<br \/>\nBuilding dependency tree<br \/>\nReading state information... Done<br \/>\nws.example.jp   The following packages were automatically installed and are no longer required:<br \/>\nws.example.jp     libjpeg-turbo8 libjpeg8 libxslt1.1 nginx-full nginx-common libgd2-noxpm<br \/>\nws.example.jp   Use 'apt-get autoremove' to remove them.<br \/>\nws.example.jp   The following packages will be REMOVED:<br \/>\nws.example.jp     nginx* redis-server*<br \/>\nws.example.jp   0 upgraded, 0 newly installed, 2 to remove and 1 not upgraded.<br \/>\nws.example.jp   After this operation, 610 kB disk space will be freed.<br \/>\n(Reading database ... 100734 files and directories currently installed.)<br \/>\nws.example.jp   Removing nginx ...<br \/>\nws.example.jp   Removing redis-server ...<br \/>\nws.example.jp   Stopping redis-server: redis-server.<br \/>\nws.example.jp   Purging configuration files for redis-server ...<br \/>\nws.example.jp   dpkg: warning: while removing redis-server, directory '\/var\/log\/redis' not empty so not removed.<br \/>\nws.example.jp   Processing triggers for man-db ...<br \/>\nws.example.jp   Processing triggers for ureadahead ...<br \/>\nReading package lists... Done<br \/>\nBuilding dependency tree<br \/>\nReading state information... Done<br \/>\nnode.example.jp The following packages were automatically installed and are no longer required:<br \/>\nnode.example.jp   libjpeg-turbo8 libjpeg8 libxslt1.1 nginx-full nginx-common libgd2-noxpm<br \/>\nnode.example.jp Use 'apt-get autoremove' to remove them.<br \/>\nnode.example.jp The following packages will be REMOVED:<br \/>\nnode.example.jp   nginx* redis-server*<br \/>\nnode.example.jp 0 upgraded, 0 newly installed, 2 to remove and 1 not upgraded.<br \/>\nnode.example.jp After this operation, 610 kB disk space will be freed.<br \/>\n(Reading database ... 61316 files and directories currently installed.)<br \/>\nnode.example.jp Removing nginx ...<br \/>\nnode.example.jp Removing redis-server ...<br \/>\nnode.example.jp Stopping redis-server: redis-server.<br \/>\nnode.example.jp Purging configuration files for redis-server ...<br \/>\nnode.example.jp dpkg: warning: while removing redis-server, directory '\/var\/log\/redis' not empty so not removed.<br \/>\nnode.example.jp Processing triggers for man-db ...<br \/>\nnode.example.jp Processing triggers for ureadahead ...<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Rewrite the recipe by using loop.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"ruby\"><br \/>\nubuntu@ws:~\/chef-repo$ vi cookbooks\/multi_pkgs\/recipes\/default.rb<br \/>\n#<br \/>\n# Cookbook Name:: multi_pkgs<br \/>\n# Recipe:: default<br \/>\n#<br \/>\n# Copyright (c) 2014 The Authors, All Rights Reserved.<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"ruby\"><br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"ruby\">%w{ nginx redis-server }.each do |pkg|<br \/>\npackage pkg<br \/>\nend<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero chef_client 'name:*' -x ubuntu --sudo<br \/>\nnode.example.jp [2014-12-22T16:28:00+09:00] WARN:<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\"]<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp   - ntp<br \/>\nnode.example.jp   - multi_pkgs<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp Converging 3 resources<br \/>\nnode.example.jp Recipe: ntp::default<br \/>\nnode.example.jp   * package[ntp] action install (up to date)<br \/>\nnode.example.jp Recipe: multi_pkgs::default<br \/>\nnode.example.jp   * package[nginx] action install<br \/>\nnode.example.jp     - install version 1.1.19-1ubuntu0.6 of package nginx<br \/>\nnode.example.jp   * package[redis-server] action install<br \/>\nnode.example.jp     - install version 2:2.2.12-1build1 of package redis-server<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 2\/3 resources updated in 6.903009063 seconds<br \/>\nws.example.jp   [2014-12-22T16:28:08+09:00] WARN:<br \/>\n:<br \/>\nws.example.jp   Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp   resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\"]<br \/>\nws.example.jp   Synchronizing Cookbooks:<br \/>\nws.example.jp     - ntp<br \/>\nws.example.jp     - multi_pkgs<br \/>\nws.example.jp   Compiling Cookbooks...<br \/>\nws.example.jp   Converging 3 resources<br \/>\nws.example.jp   Recipe: ntp::default<br \/>\nws.example.jp     * package[ntp] action install (up to date)<br \/>\nws.example.jp   Recipe: multi_pkgs::default<br \/>\nws.example.jp     * package[nginx] action install<br \/>\nws.example.jp       - install version 1.1.19-1ubuntu0.6 of package nginx<br \/>\nws.example.jp     * package[redis-server] action install<br \/>\nws.example.jp       - install version 2:2.2.12-1build1 of package redis-server<br \/>\nws.example.jp<br \/>\nws.example.jp   Running handlers:<br \/>\nws.example.jp   Running handlers complete<br \/>\nws.example.jp   Chef Client finished, 2\/3 resources updated in 7.603140636 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Installation has been completed in the same way as multiple <strong>package<\/strong>s are used. Note that the number of <strong>resources<\/strong> has not been changed. This means that there are various ways to write a recipe to get the same result.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<h3>\u25cf<a href=\"#use-template\" name=\"use-template\">Using a template<\/a><\/h3>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>With Chef, it is possible to use a <a href=\"http:\/\/docs.chef.io\/templates.html\">Template<\/a> that uses <a href=\"http:\/\/magazine.rubyist.net\/?0017-BundledLibraries\">ERB<\/a> for the engine.<br \/>\nCreate a cookbook that embeds the values acquired from variables (<strong>Hello, World!<\/strong>) into a template (<strong>tmpl.hello.erb<\/strong>), and outputs as a file (<strong>\/tmp\/hello.txt<\/strong>).<br \/>\nStart with a cookbook, which is a collection of data. Name the cookbook as \"<strong>tmpl<\/strong>\" cookbook.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ chef generate cookbook cookbooks\/tmpl<br \/>\nCompiling Cookbooks...<br \/>\nRecipe: code_generator::cookbook<br \/>\n* directory[\/home\/ubuntu\/chef-repo\/cookbooks\/tmpl] action create<br \/>\n- create new directory \/home\/ubuntu\/chef-repo\/cookbooks\/tmpl<br \/>\n:<br \/>\n(diff output suppressed by config)<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>This is an <a href=\"http:\/\/docs.chef.io\/attributes.html\">Attribute<\/a> file that describes a variable. Name this file as <strong>default<\/strong> attribute since it will contain the default value.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ chef generate attribute cookbooks\/tmpl default<br \/>\nCompiling Cookbooks...<br \/>\nRecipe: code_generator::attribute<br \/>\n* directory[cookbooks\/tmpl\/attributes] action create<br \/>\n- create new directory cookbooks\/tmpl\/attributes<br \/>\n* template[cookbooks\/tmpl\/attributes\/default.rb] action create<br \/>\n- create new file cookbooks\/tmpl\/attributes\/default.rb<br \/>\n- update content in file cookbooks\/tmpl\/attributes\/default.rb from none to e3b0c4<br \/>\n(diff output suppressed by config)<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>This is the template file. As mentioned in the previous step, the file name is \"<strong>tmpl.hello.erb<\/strong>\".<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ chef generate template cookbooks\/tmpl tmpl.hello.erb<br \/>\nCompiling Cookbooks...<br \/>\nRecipe: code_generator::template<br \/>\n* directory[cookbooks\/tmpl\/templates\/default] action create<br \/>\n- create new directory cookbooks\/tmpl\/templates\/default<br \/>\n* template[cookbooks\/tmpl\/templates\/default\/tmpl.hello.erb] action create<br \/>\n- create new file cookbooks\/tmpl\/templates\/default\/tmpl.hello.erb<br \/>\n- update content in file cookbooks\/tmpl\/templates\/default\/tmpl.hello.erb from none to e3b0c4<br \/>\n(diff output suppressed by config)<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>A base structure of the tmpl cookbook has been prepared now.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ tree cookbooks\/tmpl\/<br \/>\ncookbooks\/tmpl\/<br \/>\n\u251c\u2500\u2500 Berksfile<br \/>\n\u251c\u2500\u2500 README.md<br \/>\n\u251c\u2500\u2500 attributes<br \/>\n\u2502   \u2514\u2500\u2500 default.rb<br \/>\n\u251c\u2500\u2500 chefignore<br \/>\n\u251c\u2500\u2500 metadata.rb<br \/>\n\u251c\u2500\u2500 recipes<br \/>\n\u2502   \u2514\u2500\u2500 default.rb<br \/>\n\u2514\u2500\u2500 templates<br \/>\n\u2514\u2500\u2500 default<br \/>\n\u2514\u2500\u2500 tmpl.hello.erb<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"bash\"><br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"bash\">4 directories, 7 files<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Let's create a cookbook using structure as a base.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"ruby\"><br \/>\nubuntu@ws:~\/chef-repo$ vi cookbooks\/tmpl\/attributes\/default.rb<br \/>\ndefault['tmpl']['message'] = 'Hello, World!'<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"ruby\"><br \/>\nubuntu@ws:~\/chef-repo$ vi cookbooks\/tmpl\/templates\/default\/tmpl.hello.erb<br \/>\n\"&lt;%= node['tmpl']['message'] %&gt;\"<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"ruby\"><br \/>\nubuntu@ws:~\/chef-repo$ vi cookbooks\/tmpl\/recipes\/default.rb<br \/>\n#<br \/>\n# Cookbook Name:: tmpl<br \/>\n# Recipe:: default<br \/>\n#<br \/>\n# Copyright (c) 2014 The Authors, All Rights Reserved.<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"ruby\"><br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"ruby\">template '\/tmp\/hello.txt' do<br \/>\nsource 'tmpl.hello.erb'<br \/>\nend<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Apply the template parameter to the node.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"yaml\"><br \/>\nubuntu@ws:~\/chef-repo$ knife node run_list add node.example.jp 'recipe[tmpl]'<br \/>\nnode.example.jp:<br \/>\nrun_list:<br \/>\nrecipe[ntp]<br \/>\nrecipe[multi_pkgs]<br \/>\nrecipe[tmpl]<br \/>\nubuntu@ws:~\/chef-repo$ knife node run_list add ws.example.jp 'recipe[tmpl]'<br \/>\nws.example.jp:<br \/>\nrun_list:<br \/>\nrecipe[ntp]<br \/>\nrecipe[multi_pkgs]<br \/>\nrecipe[tmpl]<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero chef_client 'name:*' -x ubuntu --sudo<br \/>\nnode.example.jp [2014-12-22T17:25:29+09:00] WARN:<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\", \"tmpl\"]<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp   - multi_pkgs<br \/>\nnode.example.jp   - ntp<br \/>\nnode.example.jp   - tmpl<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp Converging 4 resources<br \/>\nnode.example.jp Recipe: ntp::default<br \/>\nnode.example.jp   * package[ntp] action install (up to date)<br \/>\nnode.example.jp Recipe: multi_pkgs::default<br \/>\nnode.example.jp   * package[nginx] action install (up to date)<br \/>\nnode.example.jp   * package[redis-server] action install (up to date)<br \/>\nnode.example.jp Recipe: tmpl::default<br \/>\nnode.example.jp   * template[\/tmp\/hello.txt] action create<br \/>\nnode.example.jp     - create new file \/tmp\/hello.txt<br \/>\nnode.example.jp     - update content in file \/tmp\/hello.txt from none to 3d06fb<br \/>\nnode.example.jp     --- \/tmp\/hello.txt  2014-12-22 17:25:30.600670333 +0900<br \/>\nnode.example.jp     +++ \/tmp\/chef-rendered-template20141222-9137-1tt4lvn    2014-12-22 17:25:30.600670333 +0900<br \/>\nnode.example.jp     @@ -1 +1,2 @@<br \/>\nnode.example.jp     +\"Hello, World!\"<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 1\/4 resources updated in 1.531860219 seconds<br \/>\nws.example.jp   [2014-12-22T17:25:31+09:00] WARN:<br \/>\n:<br \/>\nws.example.jp   Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp   resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\", \"tmpl\"]<br \/>\nws.example.jp   Synchronizing Cookbooks:<br \/>\nws.example.jp     - ntp<br \/>\nws.example.jp     - multi_pkgs<br \/>\nws.example.jp     - tmpl<br \/>\nws.example.jp   Compiling Cookbooks...<br \/>\nws.example.jp   Converging 4 resources<br \/>\nws.example.jp   Recipe: ntp::default<br \/>\nws.example.jp     * package[ntp] action install (up to date)<br \/>\nws.example.jp   Recipe: multi_pkgs::default<br \/>\nws.example.jp     * package[nginx] action install (up to date)<br \/>\nws.example.jp     * package[redis-server] action install (up to date)<br \/>\nws.example.jp   Recipe: tmpl::default<br \/>\nws.example.jp     * template[\/tmp\/hello.txt] action create<br \/>\nws.example.jp       - create new file \/tmp\/hello.txt<br \/>\nws.example.jp       - update content in file \/tmp\/hello.txt from none to 3d06fb<br \/>\nws.example.jp       --- \/tmp\/hello.txt  2014-12-22 17:25:33.028000026 +0900<br \/>\nws.example.jp       +++ \/tmp\/chef-rendered-template20141222-9405-1e5lqms    2014-12-22 17:25:33.028000026 +0900<br \/>\nws.example.jp       @@ -1 +1,2 @@<br \/>\nws.example.jp       +\"Hello, World!\"<br \/>\nws.example.jp<br \/>\nws.example.jp   Running handlers:<br \/>\nws.example.jp   Running handlers complete<br \/>\nws.example.jp   Chef Client finished, 1\/4 resources updated in 1.301652536 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Make sure that the file has been created.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife ssh 'name:*' 'cat \/tmp\/hello.txt' -x ubuntu<br \/>\nws.example.jp   \"Hello, World!\"<br \/>\nnode.example.jp \"Hello, World!\"<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>You can also embed the value collected with <a href=\"http:\/\/docs.chef.io\/ohai.html\">Ohai<\/a>. Embed <strong>fqdn<\/strong> here.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"diff\"><br \/>\nubuntu@ws:~\/chef-repo$ git diff cookbooks<br \/>\ndiff --git a\/cookbooks\/tmpl\/templates\/default\/tmpl.hello.erb b\/cookbooks\/tmpl\/templates\/default\/tmpl.hello.erb<br \/>\nindex 1c1ac75..b8087c4 100644<br \/>\n--- a\/cookbooks\/tmpl\/templates\/default\/tmpl.hello.erb<br \/>\n+++ b\/cookbooks\/tmpl\/templates\/default\/tmpl.hello.erb<br \/>\n@@ -1 +1 @@<br \/>\n-\"&lt;%= node['tmpl']['message'] %&gt;\"<br \/>\n+&lt;%= node['fqdn'] %&gt; says \"&lt;%= node['tmpl']['message'] %&gt;\"<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Apply the fqdn parameter to the node.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero chef_client 'name:*' -x ubuntu --sudo<br \/>\nnode.example.jp [2014-12-22T17:29:34+09:00] WARN:<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\", \"tmpl\"]<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp   - multi_pkgs<br \/>\nnode.example.jp   - tmpl<br \/>\nnode.example.jp   - ntp<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp Converging 4 resources<br \/>\nnode.example.jp Recipe: ntp::default<br \/>\nnode.example.jp   * package[ntp] action install (up to date)<br \/>\nnode.example.jp Recipe: multi_pkgs::default<br \/>\nnode.example.jp   * package[nginx] action install (up to date)<br \/>\nnode.example.jp   * package[redis-server] action install (up to date)<br \/>\nnode.example.jp Recipe: tmpl::default<br \/>\nnode.example.jp   * template[\/tmp\/hello.txt] action create<br \/>\nnode.example.jp     - update content in file \/tmp\/hello.txt from 3d06fb to f3a09e<br \/>\nnode.example.jp     --- \/tmp\/hello.txt  2014-12-22 17:25:30.600670333 +0900<br \/>\nnode.example.jp     +++ \/tmp\/chef-rendered-template20141222-9637-g2wd8o 2014-12-22 17:29:35.516354291 +0900<br \/>\nnode.example.jp     @@ -1,2 +1,2 @@<br \/>\nnode.example.jp     -\"Hello, World!\"<br \/>\nnode.example.jp     +node.example.jp says \"Hello, World!\"<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 1\/4 resources updated in 1.291272443 seconds<br \/>\nws.example.jp   [2014-12-22T17:29:36+09:00] WARN:<br \/>\n:<br \/>\nws.example.jp   Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp   resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\", \"tmpl\"]<br \/>\nws.example.jp   Synchronizing Cookbooks:<br \/>\nws.example.jp     - ntp<br \/>\nws.example.jp     - multi_pkgs<br \/>\nws.example.jp     - tmpl<br \/>\nws.example.jp   Compiling Cookbooks...<br \/>\nws.example.jp   Converging 4 resources<br \/>\nws.example.jp   Recipe: ntp::default<br \/>\nws.example.jp     * package[ntp] action install (up to date)<br \/>\nws.example.jp   Recipe: multi_pkgs::default<br \/>\nws.example.jp     * package[nginx] action install (up to date)<br \/>\nws.example.jp     * package[redis-server] action install (up to date)<br \/>\nws.example.jp   Recipe: tmpl::default<br \/>\nws.example.jp     * template[\/tmp\/hello.txt] action create<br \/>\nws.example.jp       - update content in file \/tmp\/hello.txt from 3d06fb to 053da1<br \/>\nws.example.jp       --- \/tmp\/hello.txt  2014-12-22 17:25:33.028000026 +0900<br \/>\nws.example.jp       +++ \/tmp\/chef-rendered-template20141222-10088-1kk0bd5   2014-12-22 17:29:37.982553342 +0900<br \/>\nws.example.jp       @@ -1,2 +1,2 @@<br \/>\nws.example.jp       -\"Hello, World!\"<br \/>\nws.example.jp       +ws.example.jp says \"Hello, World!\"<br \/>\nws.example.jp<br \/>\nws.example.jp   Running handlers:<br \/>\nws.example.jp   Running handlers complete<br \/>\nws.example.jp   Chef Client finished, 1\/4 resources updated in 1.348914275 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Make sure that the file has been changed.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife ssh 'name:*' 'cat \/tmp\/hello.txt' -x ubuntu<br \/>\nws.example.jp   ws.example.jp says \"Hello, World!\"<br \/>\nnode.example.jp node.example.jp says \"Hello, World!\"<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<h3>\u25cf<a href=\"#use-notifications\" name=\"use-notifications\">Communication between resources<\/a><\/h3>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>By using <a href=\"http:\/\/docs.chef.io\/resource_common.html#notifications\">notifies or subscribes<\/a>, service can be restarted as soon as the config file is changed.<br \/>\nCreate a cookbook, which installs an <strong>nginx<\/strong> package, and places the config file (<strong>\/etc\/nginx\/sites-available\/default<\/strong>) that can only change the listen port number (<strong>listen_port<\/strong>).<br \/>\nFirstly, create a base structure of <strong>nginx<\/strong> cookbook.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ chef generate cookbook cookbooks\/nginx<br \/>\nCompiling Cookbooks...<br \/>\nRecipe: code_generator::cookbook<br \/>\n* directory[\/home\/ubuntu\/chef-repo\/cookbooks\/nginx] action create<br \/>\n- create new directory \/home\/ubuntu\/chef-repo\/cookbooks\/nginx<br \/>\n:<br \/>\nubuntu@ws:~\/chef-repo$ chef generate attribute cookbooks\/nginx default<br \/>\nCompiling Cookbooks...<br \/>\nRecipe: code_generator::attribute<br \/>\n* directory[cookbooks\/nginx\/attributes] action create<br \/>\n- create new directory cookbooks\/nginx\/attributes<br \/>\n* template[cookbooks\/nginx\/attributes\/default.rb] action create<br \/>\n- create new file cookbooks\/nginx\/attributes\/default.rb<br \/>\n- update content in file cookbooks\/nginx\/attributes\/default.rb from none to e3b0c4<br \/>\n(diff output suppressed by config)<br \/>\nubuntu@ws:~\/chef-repo$ chef generate template cookbooks\/nginx nginx.default.erb<br \/>\nCompiling Cookbooks...<br \/>\nRecipe: code_generator::template<br \/>\n* directory[cookbooks\/nginx\/templates\/default] action create<br \/>\n- create new directory cookbooks\/nginx\/templates\/default<br \/>\n* template[cookbooks\/nginx\/templates\/default\/nginx.default.erb] action create<br \/>\n- create new file cookbooks\/nginx\/templates\/default\/nginx.default.erb<br \/>\n- update content in file cookbooks\/nginx\/templates\/default\/nginx.default.erb from none to e3b0c4<br \/>\n(diff output suppressed by config)<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Let's create a cookbook now. We use <strong>notifies<\/strong> here. The same thing can be achieved by using <strong>subscribes<\/strong>, but we will neither go on to details nor explain the code examples now. Please check them on your own later.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"ruby\"><br \/>\nubuntu@ws:~\/chef-repo$ vi cookbooks\/nginx\/attributes\/default.rb<br \/>\ndefault['nginx']['listen_port'] = 80<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"ruby\"><br \/>\nubuntu@ws:~\/chef-repo$ vi cookbooks\/nginx\/templates\/default\/nginx.default.erb<br \/>\n#<br \/>\n# Generated by Chef for &lt;%= node['fqdn'] %&gt;<br \/>\n#<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"ruby\"><\/code><\/code><\/code><\/p>\n<p>server {<br \/>\nlisten &lt;%= node['nginx']['listen_port'] %&gt; default_server;<br \/>\nlisten [::]:&lt;%= node['nginx']['listen_port'] %&gt; default_server ipv6only=on;<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"ruby\"><\/code><\/code><\/code><\/p>\n<p>root \/usr\/share\/nginx\/html;<br \/>\nindex index.html index.htm;<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"ruby\"><\/code><\/code><\/code><\/p>\n<p>server_name localhost;<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"ruby\"><br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"ruby\">    location \/ {<br \/>\ntry_files $uri $uri\/ =404;<br \/>\n}<br \/>\n}<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"ruby\"><br \/>\nubuntu@ws:~\/chef-repo$ vi cookbooks\/nginx\/recipes\/default.rb<br \/>\n#<br \/>\n# Cookbook Name:: nginx<br \/>\n# Recipe:: default<br \/>\n#<br \/>\n# Copyright (c) 2014 The Authors, All Rights Reserved.<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"ruby\"><\/code><\/code><\/code><\/p>\n<p>package 'nginx'<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"ruby\"><\/code><\/code><\/code><\/p>\n<p>template '\/etc\/nginx\/sites-available\/default' do<br \/>\nsource 'nginx.default.erb'<br \/>\nnotifies :restart, 'service[nginx]'<br \/>\nend<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"ruby\"><br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"ruby\">service 'nginx' do<br \/>\nsupports :restart =&gt; true<br \/>\naction :enable<br \/>\nend<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Apply the nginx parameter to the node.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"yaml\"><br \/>\nubuntu@ws:~\/chef-repo$ knife node run_list add node.example.jp 'recipe[nginx]'<br \/>\nnode.example.jp:<br \/>\nrun_list:<br \/>\nrecipe[ntp]<br \/>\nrecipe[multi_pkgs]<br \/>\nrecipe[tmpl]<br \/>\nrecipe[nginx]<br \/>\nubuntu@ws:~\/chef-repo$ knife node run_list add ws.example.jp 'recipe[nginx]'<br \/>\nws.example.jp:<br \/>\nrun_list:<br \/>\nrecipe[ntp]<br \/>\nrecipe[multi_pkgs]<br \/>\nrecipe[tmpl]<br \/>\nrecipe[nginx]<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero chef_client 'name:*' -x ubuntu --sudo<br \/>\nnode.example.jp [2014-12-22T18:17:40+09:00] WARN:<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\", \"tmpl\", \"nginx\"]<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp   - tmpl<br \/>\nnode.example.jp   - ntp<br \/>\nnode.example.jp   - multi_pkgs<br \/>\nnode.example.jp   - nginx<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp [2014-12-22T18:17:41+09:00] WARN: Cloning resource attributes for package[nginx] from prior resource (CHEF-3694)<br \/>\nnode.example.jp [2014-12-22T18:17:41+09:00] WARN: Previous package[nginx]: \/var\/chef\/cache\/cookbooks\/multi_pkgs\/recipes\/default.rb:8:in `block in from_file'<br \/>\nnode.example.jp [2014-12-22T18:17:41+09:00] WARN: Current  package[nginx]: \/var\/chef\/cache\/cookbooks\/nginx\/recipes\/default.rb:7:in `from_file'<br \/>\nnode.example.jp Converging 7 resources<br \/>\nnode.example.jp Recipe: ntp::default<br \/>\nnode.example.jp   * package[ntp] action install (up to date)<br \/>\nnode.example.jp Recipe: multi_pkgs::default<br \/>\nnode.example.jp   * package[nginx] action install (up to date)<br \/>\nnode.example.jp   * package[redis-server] action install (up to date)<br \/>\nnode.example.jp Recipe: tmpl::default<br \/>\nnode.example.jp   * template[\/tmp\/hello.txt] action create (up to date)<br \/>\nnode.example.jp Recipe: nginx::default<br \/>\nnode.example.jp   * package[nginx] action install (up to date)<br \/>\nnode.example.jp   * template[\/etc\/nginx\/sites-available\/default] action create<br \/>\nnode.example.jp     - update content in file \/etc\/nginx\/sites-available\/default from 7fe53b to 97aa27<br \/>\nnode.example.jp     --- \/etc\/nginx\/sites-available\/default  2012-03-29 11:50:24.000000000 +0900<br \/>\nnode.example.jp     +++ \/tmp\/chef-rendered-template20141222-10157-1n5zvby   2014-12-22 18:17:42.116304044 +0900<br \/>\nnode.example.jp     @@ -1,121 +1,18 @@<br \/>\n:<br \/>\nnode.example.jp   * service[nginx] action enable (up to date)<br \/>\nnode.example.jp   * service[nginx] action restart<br \/>\nnode.example.jp     - restart service service[nginx]<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 2\/8 resources updated in 2.850105057 seconds<br \/>\nws.example.jp   [2014-12-22T18:17:44+09:00] WARN:<br \/>\n:<br \/>\nws.example.jp   Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp   resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\", \"tmpl\", \"nginx\"]<br \/>\nws.example.jp   Synchronizing Cookbooks:<br \/>\nws.example.jp     - ntp<br \/>\nws.example.jp     - tmpl<br \/>\nws.example.jp     - multi_pkgs<br \/>\nws.example.jp     - nginx<br \/>\nws.example.jp   Compiling Cookbooks...<br \/>\nws.example.jp   [2014-12-22T18:17:45+09:00] WARN: Cloning resource attributes for package[nginx] from prior resource (CHEF-3694)<br \/>\nws.example.jp   [2014-12-22T18:17:45+09:00] WARN: Previous package[nginx]: \/var\/chef\/cache\/cookbooks\/multi_pkgs\/recipes\/default.rb:8:in `block in from_file'<br \/>\nws.example.jp   [2014-12-22T18:17:45+09:00] WARN: Current  package[nginx]: \/var\/chef\/cache\/cookbooks\/nginx\/recipes\/default.rb:7:in `from_file'<br \/>\nws.example.jp   Converging 7 resources<br \/>\nws.example.jp   Recipe: ntp::default<br \/>\nws.example.jp     * package[ntp] action install (up to date)<br \/>\nws.example.jp   Recipe: multi_pkgs::default<br \/>\nws.example.jp     * package[nginx] action install (up to date)<br \/>\nws.example.jp     * package[redis-server] action install (up to date)<br \/>\nws.example.jp   Recipe: tmpl::default<br \/>\nws.example.jp     * template[\/tmp\/hello.txt] action create (up to date)<br \/>\nws.example.jp   Recipe: nginx::default<br \/>\nws.example.jp     * package[nginx] action install (up to date)<br \/>\nws.example.jp     * template[\/etc\/nginx\/sites-available\/default] action create<br \/>\nws.example.jp       - update content in file \/etc\/nginx\/sites-available\/default from 7fe53b to 223390<br \/>\nws.example.jp       --- \/etc\/nginx\/sites-available\/default  2012-03-29 11:50:24.000000000 +0900<br \/>\nws.example.jp       +++ \/tmp\/chef-rendered-template20141222-10819-d944p2    2014-12-22 18:17:45.884371929 +0900<br \/>\nws.example.jp       @@ -1,121 +1,18 @@<br \/>\n:<br \/>\nws.example.jp     * service[nginx] action enable (up to date)<br \/>\nws.example.jp     * service[nginx] action restart<br \/>\nws.example.jp       - restart service service[nginx]<br \/>\nws.example.jp<br \/>\nws.example.jp   Running handlers:<br \/>\nws.example.jp   Running handlers complete<br \/>\nws.example.jp   Chef Client finished, 2\/8 resources updated in 2.687193341 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Make sure that you can access to port 80 as specified.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"html\"><br \/>\nubuntu@ws:~\/chef-repo$ curl http:\/\/node.example.jp<\/p>\n<p><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><center><\/p>\n<p><code lang=\"html\"><code lang=\"html\"><\/code><\/code><\/p>\n<h1>404 Not Found<\/h1>\n<p><code lang=\"html\"><code lang=\"html\"><\/code><\/code><\/p>\n<p><\/center><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/code><\/code><\/code><\/p>\n<hr \/>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/code><\/code><\/code><\/p>\n<p><center>nginx\/1.1.19<\/center><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/p>\n<p>ubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"html\"><br \/>\nubuntu@ws:~\/chef-repo$ curl http:\/\/ws.example.jp<\/p>\n<p><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><center><\/p>\n<p><code lang=\"html\"><code lang=\"html\"><\/code><\/code><\/p>\n<h1>404 Not Found<\/h1>\n<p><code lang=\"html\"><code lang=\"html\"><\/code><\/code><\/p>\n<p><\/center><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/code><\/code><\/code><\/p>\n<hr \/>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/code><\/code><\/code><\/p>\n<p><center>nginx\/1.1.19<\/center><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/p>\n<p>ubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Change the port number to <strong>8080<\/strong>. You can change the attribute of the cookbook instead, but we will edit the node information stored in Chef-Repo here.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"javascript\"><br \/>\nubuntu@ws:~\/chef-repo$ knife node edit node.example.jp<br \/>\n{<br \/>\n\"name\": \"node.example.jp\",<br \/>\n\"chef_environment\": \"_default\",<br \/>\n\"normal\": {<br \/>\n\"nginx\": {<br \/>\n\"listen_port\": 8080<br \/>\n},<br \/>\n\"tags\": [<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"javascript\"><\/code><\/code><\/code><\/p>\n<p>]<br \/>\n},<br \/>\n\"run_list\": [<br \/>\n\"recipe[ntp]\",<br \/>\n\"recipe[multi_pkgs]\",<br \/>\n\"recipe[tmpl]\",<br \/>\n\"recipe[nginx]\"<br \/>\n]<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"javascript\"><br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"javascript\">}<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"javascript\"><br \/>\nubuntu@ws:~\/chef-repo$ knife node edit ws.example.jp<br \/>\n{<br \/>\n\"name\": \"ws.example.jp\",<br \/>\n\"chef_environment\": \"_default\",<br \/>\n\"normal\": {<br \/>\n\"nginx\": {<br \/>\n\"listen_port\": 8080<br \/>\n},<br \/>\n\"tags\": [<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"javascript\"><\/code><\/code><\/code><\/p>\n<p>]<br \/>\n},<br \/>\n\"run_list\": [<br \/>\n\"recipe[ntp]\",<br \/>\n\"recipe[multi_pkgs]\",<br \/>\n\"recipe[tmpl]\",<br \/>\n\"recipe[nginx]\"<br \/>\n]<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"javascript\"><br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"javascript\">}<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"diff\"><br \/>\nubuntu@ws:~\/chef-repo$ git diff<br \/>\ndiff --git a\/nodes\/node.example.jp.json b\/nodes\/node.example.jp.json<br \/>\nindex c4c6fb5..09e752e 100644<br \/>\n--- a\/nodes\/node.example.jp.json<br \/>\n+++ b\/nodes\/node.example.jp.json<br \/>\n@@ -1,6 +1,9 @@<br \/>\n{<br \/>\n\"name\": \"node.example.jp\",<br \/>\n\"normal\": {<br \/>\n+    \"nginx\": {<br \/>\n+      \"listen_port\": 8080<br \/>\n+    },<br \/>\n\"tags\": [<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"diff\"><\/code><\/code><\/code><\/p>\n<p>]<br \/>\ndiff --git a\/nodes\/ws.example.jp.json b\/nodes\/ws.example.jp.json<br \/>\nindex 9043d68..76bf9b4 100644<br \/>\n--- a\/nodes\/ws.example.jp.json<br \/>\n+++ b\/nodes\/ws.example.jp.json<br \/>\n@@ -1,6 +1,9 @@<br \/>\n{<br \/>\n\"name\": \"ws.example.jp\",<br \/>\n\"normal\": {<br \/>\n+ \"nginx\": {<br \/>\n+ \"listen_port\": 8080<br \/>\n+ },<br \/>\n\"tags\": [<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"diff\"><br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"diff\">     ]<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Apply the changed node information to the node.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><br \/>\nubuntu@ws:~\/chef-repo$ knife zero chef_client 'name:*' -x ubuntu --sudo -C 1<br \/>\nnode.example.jp [2014-12-22T18:26:40+09:00] WARN:<br \/>\n:<br \/>\nnode.example.jp Starting Chef Client, version 11.16.4<br \/>\nnode.example.jp resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\", \"tmpl\", \"nginx\"]<br \/>\nnode.example.jp Synchronizing Cookbooks:<br \/>\nnode.example.jp   - multi_pkgs<br \/>\nnode.example.jp   - tmpl<br \/>\nnode.example.jp   - ntp<br \/>\nnode.example.jp   - nginx<br \/>\nnode.example.jp Compiling Cookbooks...<br \/>\nnode.example.jp [2014-12-22T18:26:41+09:00] WARN: Cloning resource attributes for package[nginx] from prior resource (CHEF-3694)<br \/>\nnode.example.jp [2014-12-22T18:26:41+09:00] WARN: Previous package[nginx]: \/var\/chef\/cache\/cookbooks\/multi_pkgs\/recipes\/default.rb:8:in `block in from_file'<br \/>\nnode.example.jp [2014-12-22T18:26:41+09:00] WARN: Current  package[nginx]: \/var\/chef\/cache\/cookbooks\/nginx\/recipes\/default.rb:7:in `from_file'<br \/>\nnode.example.jp Converging 7 resources<br \/>\nnode.example.jp Recipe: ntp::default<br \/>\nnode.example.jp   * package[ntp] action install (up to date)<br \/>\nnode.example.jp Recipe: multi_pkgs::default<br \/>\nnode.example.jp   * package[nginx] action install (up to date)<br \/>\nnode.example.jp   * package[redis-server] action install (up to date)<br \/>\nnode.example.jp Recipe: tmpl::default<br \/>\nnode.example.jp   * template[\/tmp\/hello.txt] action create (up to date)<br \/>\nnode.example.jp Recipe: nginx::default<br \/>\nnode.example.jp   * package[nginx] action install (up to date)<br \/>\nnode.example.jp   * template[\/etc\/nginx\/sites-available\/default] action create<br \/>\nnode.example.jp     - update content in file \/etc\/nginx\/sites-available\/default from 97aa27 to 3960f9<br \/>\nnode.example.jp     --- \/etc\/nginx\/sites-available\/default  2014-12-22 18:17:42.116304044 +0900<br \/>\nnode.example.jp     +++ \/tmp\/chef-rendered-template20141222-10563-2yu0aq    2014-12-22 18:26:41.266762936 +0900<br \/>\nnode.example.jp     @@ -3,8 +3,8 @@<br \/>\nnode.example.jp      #<br \/>\nnode.example.jp<br \/>\nnode.example.jp      server {<br \/>\nnode.example.jp     -    listen 80 default_server;<br \/>\nnode.example.jp     -    listen [::]:80 default_server ipv6only=on;<br \/>\nnode.example.jp     +    listen 8080 default_server;<br \/>\nnode.example.jp     +    listen [::]:8080 default_server ipv6only=on;<br \/>\nnode.example.jp<br \/>\nnode.example.jp          root \/usr\/share\/nginx\/html;<br \/>\nnode.example.jp          index index.html index.htm;<br \/>\nnode.example.jp   * service[nginx] action enable (up to date)<br \/>\nnode.example.jp   * service[nginx] action restart<br \/>\nnode.example.jp     - restart service service[nginx]<br \/>\nnode.example.jp<br \/>\nnode.example.jp Running handlers:<br \/>\nnode.example.jp Running handlers complete<br \/>\nnode.example.jp Chef Client finished, 2\/8 resources updated in 2.28401369 seconds<br \/>\nws.example.jp   [2014-12-22T18:26:43+09:00] WARN:<br \/>\n:<br \/>\nws.example.jp   Starting Chef Client, version 11.18.0.rc.1<br \/>\nws.example.jp   resolving cookbooks for run list: [\"ntp\", \"multi_pkgs\", \"tmpl\", \"nginx\"]<br \/>\nws.example.jp   Synchronizing Cookbooks:<br \/>\nws.example.jp     - ntp<br \/>\nws.example.jp     - nginx<br \/>\nws.example.jp     - multi_pkgs<br \/>\nws.example.jp     - tmpl<br \/>\nws.example.jp   Compiling Cookbooks...<br \/>\nws.example.jp   [2014-12-22T18:26:44+09:00] WARN: Cloning resource attributes for package[nginx] from prior resource (CHEF-3694)<br \/>\nws.example.jp   [2014-12-22T18:26:44+09:00] WARN: Previous package[nginx]: \/var\/chef\/cache\/cookbooks\/multi_pkgs\/recipes\/default.rb:8:in `block in from_file'<br \/>\nws.example.jp   [2014-12-22T18:26:44+09:00] WARN: Current  package[nginx]: \/var\/chef\/cache\/cookbooks\/nginx\/recipes\/default.rb:7:in `from_file'<br \/>\nws.example.jp   Converging 7 resources<br \/>\nws.example.jp   Recipe: ntp::default<br \/>\nws.example.jp     * package[ntp] action install (up to date)<br \/>\nws.example.jp   Recipe: multi_pkgs::default<br \/>\nws.example.jp     * package[nginx] action install (up to date)<br \/>\nws.example.jp     * package[redis-server] action install (up to date)<br \/>\nws.example.jp   Recipe: tmpl::default<br \/>\nws.example.jp     * template[\/tmp\/hello.txt] action create (up to date)<br \/>\nws.example.jp   Recipe: nginx::default<br \/>\nws.example.jp     * package[nginx] action install (up to date)<br \/>\nws.example.jp     * template[\/etc\/nginx\/sites-available\/default] action create<br \/>\nws.example.jp       - update content in file \/etc\/nginx\/sites-available\/default from 223390 to f0e3c4<br \/>\nws.example.jp       --- \/etc\/nginx\/sites-available\/default  2014-12-22 18:17:45.884371929 +0900<br \/>\nws.example.jp       +++ \/tmp\/chef-rendered-template20141222-11323-n203be    2014-12-22 18:26:44.702071618 +0900<br \/>\nws.example.jp       @@ -3,8 +3,8 @@<br \/>\nws.example.jp        #<br \/>\nws.example.jp<br \/>\nws.example.jp        server {<br \/>\nws.example.jp       -    listen 80 default_server;<br \/>\nws.example.jp       -    listen [::]:80 default_server ipv6only=on;<br \/>\nws.example.jp       +    listen 8080 default_server;<br \/>\nws.example.jp       +    listen [::]:8080 default_server ipv6only=on;<br \/>\nws.example.jp<br \/>\nws.example.jp            root \/usr\/share\/nginx\/html;<br \/>\nws.example.jp            index index.html index.htm;<br \/>\nws.example.jp     * service[nginx] action enable (up to date)<br \/>\nws.example.jp     * service[nginx] action restart<br \/>\nws.example.jp       - restart service service[nginx]<br \/>\nws.example.jp<br \/>\nws.example.jp   Running handlers:<br \/>\nws.example.jp   Running handlers complete<br \/>\nws.example.jp   Chef Client finished, 2\/8 resources updated in 2.440957849 seconds<br \/>\nubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Now that the config file has been changed and nginx has been restarted. Make sure that you can access to port 8080 as specified.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"html\"><br \/>\nubuntu@ws:~\/chef-repo$ curl http:\/\/node.example.jp<br \/>\ncurl: (7) couldn't connect to host<br \/>\nubuntu@ws:~\/chef-repo$ curl http:\/\/node.example.jp:8080<\/p>\n<p><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><center><\/p>\n<p><code lang=\"html\"><code lang=\"html\"><\/code><\/code><\/p>\n<h1>404 Not Found<\/h1>\n<p><code lang=\"html\"><code lang=\"html\"><\/code><\/code><\/p>\n<p><\/center><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/code><\/code><\/code><\/p>\n<hr \/>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/code><\/code><\/code><\/p>\n<p><center>nginx\/1.1.19<\/center><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/p>\n<p>ubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"html\"><br \/>\nubuntu@ws:~\/chef-repo$ curl http:\/\/ws.example.jp<br \/>\ncurl: (7) couldn't connect to host<br \/>\nubuntu@ws:~\/chef-repo$ curl http:\/\/ws.example.jp:8080<\/p>\n<p><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><center><\/p>\n<p><code lang=\"html\"><code lang=\"html\"><\/code><\/code><\/p>\n<h1>404 Not Found<\/h1>\n<p><code lang=\"html\"><code lang=\"html\"><\/code><\/code><\/p>\n<p><\/center><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/code><\/code><\/code><\/p>\n<hr \/>\n<p><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/code><\/code><\/code><\/p>\n<p><center>nginx\/1.1.19<\/center><code lang=\"bash\"><code lang=\"bash\"><code lang=\"html\"><\/p>\n<p>ubuntu@ws:~\/chef-repo$<br \/>\n<\/code><\/code><\/code><\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<h2>\u25a0<a href=\"#conclusion\" name=\"conclusion\">Summary<\/a><\/h2>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<p>Knife-Zero is a very helpful tool that easily enables practicing Infrastructure as Code through the use of Chef without using Chef Server. One of the advantages of using Knife-Zero is that migration to Chef Server is easy when the number of nodes scales out while retaining the usability that is equivalent to Chef Server.<br \/>\nFor those who want to try practicing Infrastructure as Code, but think that Chef Server is too much to handle, we recommend using Knife-Zero first. We tried to describe this document as easily as possible for a better understanding of Knife-Zero. We hope you will experience the convenience of Knife-Zero.<\/p>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<hr \/>\n<p><code lang=\"bash\"><code lang=\"bash\"><\/code><\/code><\/p>\n<ul>\n<li><a href=\"\/news\/4489\">2014\u5e744\u670828\u65e5\u300eChef\u6d3b\u7528\u30ac\u30a4\u30c9 \u30b3\u30fc\u30c9\u3067\u306f\u3058\u3081\u308b\u69cb\u6210\u7ba1\u7406\u300f\u767a\u58f2\u3057\u307e\u3057\u305f\u3002<\/a> (Japanese article)<\/li>\n<li><a href=\"http:\/\/www.sawanoboly.net\/blog\/2014\/11\/25\/chef-solo-zero-knife-solo-zero\">Chef-Solo, Chef-Client LocalMode, Knife-Solo, Knife-Zero and us.<\/a> (Japanese article)<\/li>\n<li><a href=\"\/lab\/8323\">Migrating from Knife-Solo to Knife-Zero<\/a><\/li>\n<li><a href=\"\/lab\/6380\">Chef-Solo\u304b\u3089Chef-Client\u30ed\u30fc\u30ab\u30eb\u30e2\u30fc\u30c9\u3078\u306e\u79fb\u884c<\/a> (Japanese article)<\/li>\n<li><a href=\"\/lab\/6255\">Chef Development Kit 0.3.2\u3092\u4f7f\u3063\u3066\u307f\u3088\u3046:\u57fa\u672c\u7de8<\/a> (Japanese article)<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This is the English translation of Knife-Zero\u3067Infrastructure as Code\u3092\u59cb\u3081\u3088\u3046 (2014\/12\/24). \u25a0What is Chef? Chef is [&#8230;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[36,31],"tags":[],"class_list":["post-8962","post","type-post","status-publish","format-standard","hentry","category-chef","category-higuchi"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>[English Translation] Let&#039;s begin Infrastructure as Code with Knife-Zero #getchef - Tech Blog\uff5c\u30af\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\u30e9\u30a4\u30f3<\/title>\n<meta name=\"description\" content=\"Chef, d-higuchi |This is the English translation of Knife-Zero\u3067Infrastructure as Code\u3092\u59cb\u3081\u3088\u3046\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962\" \/>\n<meta property=\"og:locale\" content=\"ja_JP\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"[English Translation] Let&#039;s begin Infrastructure as Code with Knife-Zero #getchef - Tech Blog\uff5c\u30af\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\u30e9\u30a4\u30f3\" \/>\n<meta property=\"og:description\" content=\"Chef, d-higuchi |This is the English translation of Knife-Zero\u3067Infrastructure as Code\u3092\u59cb\u3081\u3088\u3046\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962\" \/>\n<meta property=\"og:site_name\" content=\"Tech Blog\uff5c\u30af\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\u30e9\u30a4\u30f3\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/creationline\" \/>\n<meta property=\"article:published_time\" content=\"2015-04-17T05:00:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-29T05:02:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.creationline.com\/tech-blog\/cms_x3GWkuX\/wp-content\/uploads\/2026\/01\/screenshot.png\" \/>\n\t<meta property=\"og:image:width\" content=\"470\" \/>\n\t<meta property=\"og:image:height\" content=\"394\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Daisuke Higuchi\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@creationline\" \/>\n<meta name=\"twitter:site\" content=\"@creationline\" \/>\n<meta name=\"twitter:label1\" content=\"\u57f7\u7b46\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"Daisuke Higuchi\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u63a8\u5b9a\u8aad\u307f\u53d6\u308a\u6642\u9593\" \/>\n\t<meta name=\"twitter:data2\" content=\"41\u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cloudnative\\\/chef\\\/8962#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cloudnative\\\/chef\\\/8962\"},\"author\":{\"name\":\"Daisuke Higuchi\",\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/#\\\/schema\\\/person\\\/16f1373831fb6fd17387f16ae1195206\"},\"headline\":\"[English Translation] Let&#8217;s begin Infrastructure as Code with Knife-Zero #getchef\",\"datePublished\":\"2015-04-17T05:00:07+00:00\",\"dateModified\":\"2023-08-29T05:02:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cloudnative\\\/chef\\\/8962\"},\"wordCount\":1837,\"articleSection\":[\"Chef\",\"d-higuchi\"],\"inLanguage\":\"ja\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cloudnative\\\/chef\\\/8962\",\"url\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cloudnative\\\/chef\\\/8962\",\"name\":\"[English Translation] Let's begin Infrastructure as Code with Knife-Zero #getchef - Tech Blog\uff5c\u30af\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\u30e9\u30a4\u30f3\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/#website\"},\"datePublished\":\"2015-04-17T05:00:07+00:00\",\"dateModified\":\"2023-08-29T05:02:09+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/#\\\/schema\\\/person\\\/16f1373831fb6fd17387f16ae1195206\"},\"description\":\"Chef, d-higuchi |This is the English translation of Knife-Zero\u3067Infrastructure as Code\u3092\u59cb\u3081\u3088\u3046\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cloudnative\\\/chef\\\/8962#breadcrumb\"},\"inLanguage\":\"ja\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cloudnative\\\/chef\\\/8962\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cloudnative\\\/chef\\\/8962#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"HOME\",\"item\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u30af\u30e9\u30a6\u30c9\u30cd\u30a4\u30c6\u30a3\u30d6\",\"item\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cloudnative\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Chef\",\"item\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cloudnative\\\/chef\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"[English Translation] Let&#8217;s begin Infrastructure as Code with Knife-Zero #getchef\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/#website\",\"url\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/\",\"name\":\"Tech Blog\uff5c\u30af\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\u30e9\u30a4\u30f3\",\"description\":\"\u30a2\u30b8\u30e3\u30a4\u30eb\uff06DevOps\u3001\u30af\u30e9\u30a6\u30c9\u30cd\u30a4\u30c6\u30a3\u30d6\u3001AI\uff06LLM\u306e\u5148\u7aef\u6280\u8853\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ja\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/#\\\/schema\\\/person\\\/16f1373831fb6fd17387f16ae1195206\",\"name\":\"Daisuke Higuchi\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ja\",\"@id\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cms_x3GWkuX\\\/wp-content\\\/uploads\\\/2023\\\/08\\\/d-higuchi-wp-icon-230x230.png\",\"url\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cms_x3GWkuX\\\/wp-content\\\/uploads\\\/2023\\\/08\\\/d-higuchi-wp-icon-230x230.png\",\"contentUrl\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/cms_x3GWkuX\\\/wp-content\\\/uploads\\\/2023\\\/08\\\/d-higuchi-wp-icon-230x230.png\",\"caption\":\"Daisuke Higuchi\"},\"description\":\"Chef\u30fbDocker\u30fbMirantis\u88fd\u54c1\u306a\u3069\u306e\u6280\u8853\u8981\u7d20\u306b\u52a0\u3048\u3066\u3001\u4f1a\u8b70\u306e\u9032\u3081\u65b9\u30fb\u6587\u7ae0\u306e\u66f8\u304d\u65b9\u306a\u3069\u306e\u696d\u52d9\u6539\u5584\u306b\u3082\u53d6\u308a\u7d44\u3093\u3067\u3044\u307e\u3059\u3002\u300cChef\u6d3b\u7528\u30ac\u30a4\u30c9\u300d\u5171\u8457\u306e\u307b\u304b\u3001Debian Official Developer\u3082\u3084\u3063\u3066\u3044\u307e\u3059\u3002\",\"url\":\"https:\\\/\\\/www.creationline.com\\\/tech-blog\\\/author\\\/higuchi\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"[English Translation] Let's begin Infrastructure as Code with Knife-Zero #getchef - Tech Blog\uff5c\u30af\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\u30e9\u30a4\u30f3","description":"Chef, d-higuchi |This is the English translation of Knife-Zero\u3067Infrastructure as Code\u3092\u59cb\u3081\u3088\u3046","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962","og_locale":"ja_JP","og_type":"article","og_title":"[English Translation] Let's begin Infrastructure as Code with Knife-Zero #getchef - Tech Blog\uff5c\u30af\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\u30e9\u30a4\u30f3","og_description":"Chef, d-higuchi |This is the English translation of Knife-Zero\u3067Infrastructure as Code\u3092\u59cb\u3081\u3088\u3046","og_url":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962","og_site_name":"Tech Blog\uff5c\u30af\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\u30e9\u30a4\u30f3","article_publisher":"https:\/\/www.facebook.com\/creationline","article_published_time":"2015-04-17T05:00:07+00:00","article_modified_time":"2023-08-29T05:02:09+00:00","og_image":[{"width":470,"height":394,"url":"https:\/\/www.creationline.com\/tech-blog\/cms_x3GWkuX\/wp-content\/uploads\/2026\/01\/screenshot.png","type":"image\/png"}],"author":"Daisuke Higuchi","twitter_card":"summary_large_image","twitter_creator":"@creationline","twitter_site":"@creationline","twitter_misc":{"\u57f7\u7b46\u8005":"Daisuke Higuchi","\u63a8\u5b9a\u8aad\u307f\u53d6\u308a\u6642\u9593":"41\u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962#article","isPartOf":{"@id":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962"},"author":{"name":"Daisuke Higuchi","@id":"https:\/\/www.creationline.com\/tech-blog\/#\/schema\/person\/16f1373831fb6fd17387f16ae1195206"},"headline":"[English Translation] Let&#8217;s begin Infrastructure as Code with Knife-Zero #getchef","datePublished":"2015-04-17T05:00:07+00:00","dateModified":"2023-08-29T05:02:09+00:00","mainEntityOfPage":{"@id":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962"},"wordCount":1837,"articleSection":["Chef","d-higuchi"],"inLanguage":"ja"},{"@type":"WebPage","@id":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962","url":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962","name":"[English Translation] Let's begin Infrastructure as Code with Knife-Zero #getchef - Tech Blog\uff5c\u30af\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\u30e9\u30a4\u30f3","isPartOf":{"@id":"https:\/\/www.creationline.com\/tech-blog\/#website"},"datePublished":"2015-04-17T05:00:07+00:00","dateModified":"2023-08-29T05:02:09+00:00","author":{"@id":"https:\/\/www.creationline.com\/tech-blog\/#\/schema\/person\/16f1373831fb6fd17387f16ae1195206"},"description":"Chef, d-higuchi |This is the English translation of Knife-Zero\u3067Infrastructure as Code\u3092\u59cb\u3081\u3088\u3046","breadcrumb":{"@id":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962#breadcrumb"},"inLanguage":"ja","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef\/8962#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"HOME","item":"https:\/\/www.creationline.com\/tech-blog"},{"@type":"ListItem","position":2,"name":"\u30af\u30e9\u30a6\u30c9\u30cd\u30a4\u30c6\u30a3\u30d6","item":"https:\/\/www.creationline.com\/tech-blog\/cloudnative"},{"@type":"ListItem","position":3,"name":"Chef","item":"https:\/\/www.creationline.com\/tech-blog\/cloudnative\/chef"},{"@type":"ListItem","position":4,"name":"[English Translation] Let&#8217;s begin Infrastructure as Code with Knife-Zero #getchef"}]},{"@type":"WebSite","@id":"https:\/\/www.creationline.com\/tech-blog\/#website","url":"https:\/\/www.creationline.com\/tech-blog\/","name":"Tech Blog\uff5c\u30af\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\u30e9\u30a4\u30f3","description":"\u30a2\u30b8\u30e3\u30a4\u30eb\uff06DevOps\u3001\u30af\u30e9\u30a6\u30c9\u30cd\u30a4\u30c6\u30a3\u30d6\u3001AI\uff06LLM\u306e\u5148\u7aef\u6280\u8853","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.creationline.com\/tech-blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ja"},{"@type":"Person","@id":"https:\/\/www.creationline.com\/tech-blog\/#\/schema\/person\/16f1373831fb6fd17387f16ae1195206","name":"Daisuke Higuchi","image":{"@type":"ImageObject","inLanguage":"ja","@id":"https:\/\/www.creationline.com\/tech-blog\/cms_x3GWkuX\/wp-content\/uploads\/2023\/08\/d-higuchi-wp-icon-230x230.png","url":"https:\/\/www.creationline.com\/tech-blog\/cms_x3GWkuX\/wp-content\/uploads\/2023\/08\/d-higuchi-wp-icon-230x230.png","contentUrl":"https:\/\/www.creationline.com\/tech-blog\/cms_x3GWkuX\/wp-content\/uploads\/2023\/08\/d-higuchi-wp-icon-230x230.png","caption":"Daisuke Higuchi"},"description":"Chef\u30fbDocker\u30fbMirantis\u88fd\u54c1\u306a\u3069\u306e\u6280\u8853\u8981\u7d20\u306b\u52a0\u3048\u3066\u3001\u4f1a\u8b70\u306e\u9032\u3081\u65b9\u30fb\u6587\u7ae0\u306e\u66f8\u304d\u65b9\u306a\u3069\u306e\u696d\u52d9\u6539\u5584\u306b\u3082\u53d6\u308a\u7d44\u3093\u3067\u3044\u307e\u3059\u3002\u300cChef\u6d3b\u7528\u30ac\u30a4\u30c9\u300d\u5171\u8457\u306e\u307b\u304b\u3001Debian Official Developer\u3082\u3084\u3063\u3066\u3044\u307e\u3059\u3002","url":"https:\/\/www.creationline.com\/tech-blog\/author\/higuchi"}]}},"_links":{"self":[{"href":"https:\/\/www.creationline.com\/tech-blog\/wp-json\/wp\/v2\/posts\/8962","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.creationline.com\/tech-blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.creationline.com\/tech-blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.creationline.com\/tech-blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.creationline.com\/tech-blog\/wp-json\/wp\/v2\/comments?post=8962"}],"version-history":[{"count":1,"href":"https:\/\/www.creationline.com\/tech-blog\/wp-json\/wp\/v2\/posts\/8962\/revisions"}],"predecessor-version":[{"id":65777,"href":"https:\/\/www.creationline.com\/tech-blog\/wp-json\/wp\/v2\/posts\/8962\/revisions\/65777"}],"wp:attachment":[{"href":"https:\/\/www.creationline.com\/tech-blog\/wp-json\/wp\/v2\/media?parent=8962"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.creationline.com\/tech-blog\/wp-json\/wp\/v2\/categories?post=8962"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.creationline.com\/tech-blog\/wp-json\/wp\/v2\/tags?post=8962"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}