Chef Provisioning a Chef Server Cluster - ChefConf 2015
- 3. Chef Provisioning a Chef Server Cluster
Joshua Timberman
joshua@chef.io
@jtimberman
https://www.flickr.com/photos/jamidwyer/2844765976
- 4. Before we begin, provisioning a Chef Server:
• Run chef-client...
• Which talks to a different Chef Server...
• Which downloads a recipe that...
• Creates machines that run chef-client...
• That install Chef Server packages...
• Which then run chef-server-ctl reconfigure...
• Which runs chef-solo to configure the Chef Server
- 7. Where are we going*?
*And why are we in this handbasket?
https://www.flickr.com/photos/steevithak/6936667291
- 10. Bootstrap a Chef Server with Chef Solo
sudo
chef-‐solo
-‐c
/etc/chef/solo.rb
-‐j
~/chef.json
-‐r
http://s3.amazonaws.com/chef-‐solo/bootstrap-‐latest.tar.gz
- 11. As it turns out...
This is a pretty good idea!
https://www.flickr.com/photos/nao904/6084536885
- 12. chef-server-ctl reconfigure
frontend-‐chef-‐server%
sudo
chef-‐server-‐ctl
reconfigure
Starting
Chef
Client,
version
11.18.0
Compiling
Cookbooks...
Recipe:
private-‐chef::default
....
Recipe:
private-‐chef::default
*
file[/etc/opscode/chef-‐server-‐running.json]
action
create
(up
to
date)
Running
handlers:
Running
handlers
complete
Chef
Client
finished,
7/228
resources
updated
in
7.282379304
seconds
opscode
Reconfigured!
- 14. Hosted Chef... is different (and that's the problem)
• Built using Chef cookbooks
• (yay! ...but)
• Many forked community cookbooks
• (before berkshelf/librarian)
• One cookbook per component/service
• (postgresql, erchef, authz, rabbitmq, solr, etc)
• Growth over time
• (over 10k commits)
• Not the same as what customers use
• (chef-server-ctl reconfigure vs "knife ssh and chef-client")
- 16. Chef Server 12
"There is One Chef Server,
and it is Open Source"
- Adam Jacob
https://www.chef.io/blog/2014/09/08/there-is-one-chef-server-and-it-is-open-source/
- 17. You've probably heard this by now...
• Multi-tenancy - required feature for Hosted Chef
• Chef Push Jobs is opened now
• Remove tension between Open Source Chef and
Enterprise Chef codebase
• Remove tension between Hosted Enterprise Chef
and Enterprise Chef code, too
- 18. Current state: Installing
Chef Server 12
Or, "this is how you do it manually per the
documentation at docs.chef.io"
http://docs.chef.io/server/install_server.html
- 19. Installing Chef Server 12
sudo
dpkg
-‐i
chef-‐server-‐core*.deb
sudo
vi
/etc/opscode/chef-‐server.rb
sudo
chef-‐server-‐ctl
reconfigure
- 20. Or there's a cookbook for that...
curl
-‐L
https://www.chef.io/chef/install.sh
|
sudo
bash
sudo
mkdir
-‐p
/var/chef/cache
/var/chef/cookbooks
wget
-‐qO-‐
https://supermarket.chef.io/cookbooks/chef-‐server/
download
|
sudo
tar
xvzC
/var/chef/cookbooks
wget
-‐qO-‐
https://supermarket.chef.io/cookbooks/chef-‐server-‐
ingredient/download
|
sudo
tar
xvzC
/var/chef/cookbooks
wget
-‐qO-‐
https://supermarket.chef.io/cookbooks/packagecloud/
download
|
sudo
tar
xvzC
/var/chef/cookbooks
sudo
chef-‐solo
-‐o
'recipe[chef-‐server::default]'
- 21. But if you want a cluster...
##
On
the
first
node
("bootstrap
backend")
sudo
dpkg
-‐i
chef-‐server-‐core*.deb
sudo
vi
/etc/opscode/chef-‐server.rb
##
manage
some
server
blocks
for
the
cluster
per
docs
sudo
chef-‐server-‐ctl
reconfigure
sudo
rsync
-‐avz
/etc/opscode
root@frontend.example.com:/etc
##
On
the
second
node
("frontend")
sudo
dpkg
-‐i
chef-‐server-‐core*.deb
sudo
chef-‐server-‐ctl
reconfigure
- 23. Wait. What was that?
##
On
the
first
node
("bootstrap
backend")
sudo
dpkg
-‐i
chef-‐server-‐core*.deb
sudo
vi
/etc/opscode/chef-‐server.rb
##
manage
some
server
blocks
according
to
docs.chef.io...
sudo
chef-‐server-‐ctl
reconfigure
sudo
rsync
-‐avz
/etc/opscode
root@frontend.example.com:/etc
##
On
the
second
node
("frontend")
sudo
dpkg
-‐i
chef-‐server-‐core*.deb
sudo
chef-‐server-‐ctl
reconfigure
- 29. What is Chef Provisioning?
• Previously known as "Chef Metal"
• Manage machines as Chef resources
• Various provisioners available
• several come with ChefDK, e.g., aws, azure
• Available as rubygems
• Makes it easy to reason about standing up a cluster
- 30. Chef Provisioning has `machine` resources
machine
'database'
do
recipe
'example-‐postgresql::server'
end
machine
'cache'
do
recipe
'example-‐memcached'
end
machine
'www1'
do
recipe
'example-‐nginx'
end
machine
'www2'
do
recipe
'example-‐nginx
end
- 31. Chef Provisioning extends Chef's Recipe DSL
#
AWS
EC2...
with_driver('aws::us-‐west-‐2')
with_machine_options(
:bootstrap_options
=>
{
:key_name
=>
'hc-‐metal-‐provisioner',
:image_id
=>
'ami-‐b99ed989',
:instance_type
=>
'm3.medium'
}
)
#
Microsoft
Azure...
with_driver('azure')
with_machine_options(
:image_id
=>
'Ubuntu-‐14_04_1-‐LTS-‐amd64-‐server-‐20140927-‐en-‐us-‐30GB',
:bootstrap_options
=>
{
:vm_size
=>
'Standard_D1',
:other_options
=>
'Slides
are
only
so
big...'
}
)
- 33. Chef Provisioning a Chef Server Cluster
machine
'backend'
do
recipe
'chef-‐server-‐cluster::bootstrap-‐backend'
end
machine
'frontend'
do
recipe
'chef-‐server-‐cluster::frontend'
end
machine
'analytics'
do
recipe
'chef-‐server-‐cluster::analytics'
end
- 36. Chef Provisioning Requires a... Provisioner
• What is a provisioner?
• What does it provision?
• What does it need on the Chef Server?
- 37. AWS Authentication
%
cat
~/.aws/config
[default]
aws_access_key_id=AN_ACCESS_KEY_FOR_YOUR_IAM_USER
aws_secret_access_key=MATCHING_SECRET_KEY
- 38. SSH Access - Provisioner options
{
:ssh_username
=>
"ubuntu",
:bootstrap_options
=>
{
:key_name
=>
"hc-‐metal-‐provisioner"
}
}
- 39. SSH Keys - Data Bag Item
{
"id":
"hc-‐metal-‐provisioner",
"private_ssh_key":
"-‐-‐-‐-‐-‐BEGIN
RSA
PRIVATE
KEY-‐-‐-‐-‐-‐nSNIP-‐-‐-‐-‐-‐END
RSA
PRIVATE
KEY-‐-‐-‐-‐-‐
n"
}
- 40. setup-ssh-keys recipe
ssh_keys
=
data_bag_item('secrets',
'hc-‐metal-‐provisioner')
key_dir
=
File.join(Dir.home,
'.ssh')
directory
key_dir
do
recursive
true
end
file
File.join(key_dir,
key_name)
do
content
ssh_keys['private_ssh_key']
sensitive
true
end
- 44. Checkpoint!
• ./.chef/config.rb for knife and chef-client
• Uploaded cookbooks (using Policyfiles*)
• Uploaded data bags
• AWS authentication credentials in ~/.aws/config
• SSH private key in ~/.ssh/keyname
* Due to time constraints, Policyfile discussion is not appearing in this talk
- 45. Provisioner node run list
%
knife
node
show
chefconf-‐provisioner
Node
Name:
chefconf-‐provisioner
Environment:
_default
FQDN:
IP:
10.13.37.102
Run
List:
recipe[chef-‐server-‐cluster::cluster-‐provision]
Roles:
Recipes:
chef-‐server-‐cluster::cluster-‐provision,
chef-‐server-‐
cluster::setup-‐provisioner,
chef-‐server-‐cluster::setup-‐ssh-‐keys
Platform:
mac_os_x
10.10.2
Tags:
- 46. chef-server-cluster cookbook attributes
default['chef-server-cluster']['topology'] = 'tier'
default['chef-server-cluster']['role'] = 'frontend'
default['chef-server-cluster']['bootstrap']['enable'] = false
default['chef-server-cluster']['chef-provisioner-key-name'] = ‘keyname’
default['chef-server-cluster']['driver'] = {
'gems' => [
{
'name' => 'chef-provisioning-aws',
'require' => 'chef/provisioning/aws_driver'
}
],
'with-parameter' => 'aws::us-west-2'
}
default['chef-server-cluster']['driver']['machine_options'] = {
'ssh_username' => 'ubuntu',
'use_private_ip_for_ssh' => false,
'bootstrap_options' => {
'key_name' => ‘keyname’,
'image_id' => 'ami-b99ed989',
'instance_type' => 'm3.medium'
}
}
- 48. What that actually looks like...
chef_gem
'chef-‐provisioning-‐aws'
require
'chef/provisioning/aws'
with_driver('aws::us-‐west-‐2')
with_machine_options({
:ssh_username
=>
'ubuntu',
:use_private_ip_for_ssh
=>
false,
:bootstrap_options
=>
{
:key_name
=>
'hc-‐metal-‐provisioner',
:image_id
=>
'ami-‐b99ed989',
:instance_type
=>'m3.medium'
}
})
- 49. So in theory...
{
"id":
"azure-‐provisioner",
"default_attributes":
{
"chef-‐server-‐cluster":
{
"driver":
{
"gems":
[{
"name":
"chef-‐provisioning-‐azure",
"require":
"chef/provisioning/azure_driver"
}],
"with-‐parameter":
"azure",
"machine_options":
{
"bootstrap_options":
{
"cloud_service_name":
"chef-‐provisioner",
"storage_aaccount_name":
"chef-‐provisioner",
"vm_size":
"Standard_D1",
"location":
"West
US",
"tcp_endpoints":
"80:80"
},
"image_id":
"b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-‐14_04_1-‐LTS-‐amd64-‐server-‐20140927-‐en-‐us-‐30GB",
"password":
"SshKeysArentSupportedYet"
}
}
}
}
}
- 51. machine resource
<machine[bootstrap-‐backend]
@name:
"bootstrap-‐backend"
@allowed_actions:
[:nothing,
:allocate,
:ready,
:setup,
:converge,
:converge_only,
:d
estroy,
:stop]
@action:
[:converge]
@chef_server:
{
:chef_server_url=>"https://api.opscode.com/organizations/
jtimberman-‐chefconf",
:options=>{
:client_name=>"jtimberman",
:signing_key_filename=>"/Users/jtimberman/.chef/
jtimberman.pem"
}
}
- 52. machine resource continued
@driver:
"aws::us-‐west-‐2"
@machine_options:
{
"ssh_username"=>"ubuntu",
"use_private_ip_for_ssh"=>false,
"bootstrap_options"=>{
"key_name"=>"hc-‐metal-‐provisioner",
"image_id"=>"ami-‐b99ed989",
"instance_type"=>"m3.medium"
}
}
@run_list_modifiers:
[#<Chef::RunList::RunListItem:0x007f8cbe394d90
@version=nil,
@type=:recipe,
@name="chef-‐server-‐cluster::bootstrap">]
@ohai_hints:
{"ec2"=>"{}"}
@converge:
true
>
- 53. Data bags
chef_server/topology.json
{
"id":
"topology",
"topology":
"tier",
"disabled_svcs":
[],
"enabled_svcs":
[],
"vips":
[],
"dark_launch":
{
"actions":
true
},
"api_fqdn":
"chef.jtimberman.name",
"analytics_fqdn":
"analytics.jtimberman.name",
"notification_email":
"ops@jtimberman.name"
}
- 54. Configuring the Cluster - bootstrap recipe
chef_server_config
=
data_bag_item('chef_server',
'topology').to_hash
chef_server_config.delete('id')
chef_servers
=
search('node',
'chef-‐server-‐cluster_role:backend').map
do
|server|
{
:fqdn
=>
server['fqdn'],
:ipaddress
=>
server['ipaddress'],
:bootstrap
=>
server['chef-‐server-‐cluster']['bootstrap']['enable'],
:role
=>
server['chef-‐server-‐cluster']['role']
}
end
if
chef_servers.empty?
chef_servers
=
[
{
:fqdn
=>
node['fqdn'],
:ipaddress
=>
node['ipaddress'],
:bootstrap
=>
true,
:role
=>
'backend'
}
]
end
chef_server_config['vips']
=
{
'rabbitmq'
=>
node['ipaddress']
}
chef_server_config['rabbitmq']
=
{
'node_ip_address'
=>
'0.0.0.0'
}
- 55. Merge the configuration
#
Merge
the
attributes
with
the
data
bag
values,
and
the
search
#
results
for
other
servers.
node.default['chef-‐server-‐cluster'].merge!(chef_server_config)
- 57. Render configuration: /etc/opscode/chef-server.rb
topology
'<%=
@chef_server_config['topology']
%>'
api_fqdn
'<%=
@chef_server_config['api_fqdn']
%>'
#
Analytics
configuration
dark_launch['actions']
=
<%=
@chef_server_config['dark_launch']['actions']
%>
<%
if
@chef_server_config.has_key?('vips')
-‐%>
<%
@chef_server_config['vips'].each
do
|vip_name,
vip_add|
-‐%>
<%=
vip_name
%>['vip']
=
'<%=
vip_add
%>'
<%
end
-‐%>
<%
end
-‐%>
<%
if
@chef_server_config.has_key?('rabbitmq')
&&
@chef_server_config['rabbitmq'].has_key?('node_ip_address')
-‐%>
rabbitmq['node_ip_address']
=
'<%=
@chef_server_config['rabbitmq']['node_ip_address']
%>'
<%
end
-‐%>
oc_id['applications']
=
{
'analytics'
=>
{
'redirect_uri'
=>
'https://<%=
@chef_server_config['analytics_fqdn']
%>'
}
}
- 58. /etc/opscode/chef-server.rb
#
Server
blocks
<%
@chef_servers.each
do
|server|
-‐%>
server
'<%=
server[:fqdn]
%>',
:ipaddress
=>
'<%=
server[:ipaddress]
%>',
<%
if
server[:bootstrap]
-‐%>
:bootstrap
=>
true,
<%
end
-‐%>
:role
=>
'<%=
server[:role]
%>'
<%
if
server[:role]
==
'backend'
-‐%>
backend_vip
'<%=
server[:fqdn]
%>',
:ipaddress
=>
'<%=
server[:ipaddress]
%>'
<%
end
-‐%>
<%
end
-‐%>
`server` blocks describe
frontend and backend nodes
- 59. Rendered: backend
topology
'tier'
api_fqdn
'chef.jtimberman.name'
dark_launch['actions']
=
true
rabbitmq['vip']
=
'172.31.12.241'
rabbitmq['node_ip_address']
=
'0.0.0.0'
oc_id['applications']
=
{
'analytics'
=>
{
'redirect_uri'
=>
'https://analytics.jtimberman.name'
}
}
server
'ip-‐172-‐31-‐12-‐241.us-‐west-‐2.compute.internal',
:ipaddress
=>
'172.31.12.241',
:bootstrap
=>
true,
:role
=>
'backend'
backend_vip
'ip-‐172-‐31-‐12-‐241.us-‐west-‐2.compute.internal',
:ipaddress
=>
'172.31.12.241'
- 60. Rendered: frontend
topology
'tier'
api_fqdn
'chef.jtimberman.name'
dark_launch['actions']
=
true
oc_id['applications']
=
{
'analytics'
=>
{
'redirect_uri'
=>
'https://analytics.jtimberman.name'
}
}
server
'ip-‐172-‐31-‐12-‐241.us-‐west-‐2.compute.internal',
:ipaddress
=>
'172.31.12.241',
:bootstrap
=>
true,
:role
��=>
'backend'
backend_vip
'ip-‐172-‐31-‐12-‐241.us-‐west-‐2.compute.internal',
:ipaddress
=>
'172.31.12.241'
server
'ip-‐172-‐31-‐11-‐8.us-‐west-‐2.compute.internal',
:ipaddress
=>
'172.31.11.8',
:role
=>
'frontend'
- 62. /etc/opscode-analytics/actions-source.json
{
"private_chef":
{
"api_fqdn":
"chef.jtimberman.name",
"oc_id_application":
{
"name":
"analytics",
"uid":
"56d493b4ef2290cb29d9e73d34bd89688667b9f0d4583ac273e6e9de79ba3cb7",
"secret":
"Generated-‐long-‐secret",
"redirect_uri":
"https://analytics.jtimberman.name"
},
"rabbitmq_host":
"172.31.10.165",
"rabbitmq_port":
"5672",
"rabbitmq_vhost":
"/analytics",
"rabbitmq_exchange":
"actions",
"rabbitmq_user":
"actions",
"rabbitmq_password":
"generated-‐long-‐secret"
}
the bootstrap backend node
- 64. chef-server-ingredient cookbook
• What is an ingredient?
• Clever, what's an addon?
• What does the cookbook do?
• How does the resource work?
• Primitive resource for installing/managing Chef Server
add-ons
- 65. This automates these manual steps
%
sudo
chef-‐server-‐ctl
install
opscode-‐manage
%
sudo
opscode-‐manage-‐ctl
reconfigure
- 66. chef_server_ingredient resources...
chef_server_ingredient
'chef-‐server-‐core'
do
notifies
:reconfigure,
'chef_server_ingredient[chef-‐server-‐core]'
end
chef_server_ingredient
'opscode-‐reporting'
do
notifies
:reconfigure,
'chef_server_ingredient[opscode-‐reporting]'
end
chef_server_ingredient
'opscode-‐manage'
do
notifies
:reconfigure,
'chef_server_ingredient[opscode-‐manage]'
end
chef_server_ingredient
'opscode-‐analytics'
do
notifies
:reconfigure,
'chef_server_ingredient[opscode-‐analytics]'
end
- 69. chef_server_ingredient
action
:install
do
packagecloud_repo
'chef/stable'
do
type
value_for_platform_family(:debian
=>
'deb',
:rhel
=>
'rpm')
end
package
new_resource.package_name
do
options
new_resource.options
version
new_resource.version
end
end
action
:reconfigure
do
ctl_cmd
=
ctl_command
execute
"#{new_resource.package_name}-‐reconfigure"
do
command
"#{ctl_cmd}
reconfigure"
end
end
- 70. Omnibus package pattern is consistent:
• Install the package
• Write the configuration*
• Run the reconfigure command
• Configuration can happen first - and does with the
Chef Provisioning recipes
* or rsync it from a node, RIGHT?
- 72. Hello, machine_file!
%w{
actions-‐source.json
webui_priv.pem
}.each
do
|analytics_file|
machine_file
"/etc/opscode-‐analytics/#{analytics_file}"
do
local_path
"/tmp/stash/#{analytics_file}"
machine
'bootstrap-‐backend'
action
:download
end
end
%w{
pivotal.pem
webui_pub.pem
}.each
do
|opscode_file|
machine_file
"/etc/opscode/#{opscode_file}"
do
local_path
"/tmp/stash/#{opscode_file}"
machine
'bootstrap-‐backend'
action
:download
end
end
- 73. And the 'files' property of machine resource
machine
'frontend'
do
recipe
'chef-‐server-‐cluster::frontend'
action
:converge
converge
true
files('/etc/opscode/webui_priv.pem'
=>
'/tmp/stash/webui_priv.pem',
'/etc/opscode/webui_pub.pem'
=>
'/tmp/stash/webui_pub.pem',
'/etc/opscode/pivotal.pem'
=>
'/tmp/stash/pivotal.pem')
end
machine
'analytics'
do
recipe
'chef-‐server-‐cluster::analytics'
action
:converge
converge
true
files('/etc/opscode-‐analytics/actions-‐source.json'
=>
'/tmp/stash/actions-‐source.json',
'/etc/opscode-‐analytics/webui_priv.pem'
=>
'/tmp/stash/webui_priv.pem')
end
- 74. Sure, we could rsync in the recipe...
• But then we have to setup SSH keys between the
nodes
• And all files in /etc/opscode, including ones put there
by someone that shouldn't be there...
- 75. chef-client on the provisioner
%
CHEF_NODE=chefconf-‐provisioner
chef-‐client
-‐c
.chef/config.rb
Starting
Chef
Client,
version
12.0.3
[2015-‐02-‐18T14:28:12-‐07:00]
WARN:
Using
experimental
Policyfile
feature
resolving
cookbooks
for
run
list:
["chef-‐server-‐cluster::cluster-‐
provision@0.0.9
(e1e803c)"]
Synchronizing
Cookbooks:
-‐
chef-‐server-‐ingredient
-‐
chef-‐server-‐cluster
-‐
apt
-‐
packagecloud
-‐
chef-‐vault
Compiling
Cookbooks...
...
SNIP
converging
3
machines
...
Chef
Client
finished,
11/16
resources
updated
in
1248.519725
seconds
- 76. machine resources converging
*
machine[bootstrap-‐backend]
action
converge
-‐
Create
bootstrap-‐backend
with
AMI
ami-‐b99ed989
in
us-‐west-‐2
-‐
create
node
bootstrap-‐backend
at
https://api.opscode.com/organizations/jtimberman-‐chefconf
-‐
update
run_list
from
[]
to
["recipe[chef-‐server-‐cluster::bootstrap]"]
-‐
waiting
for
bootstrap-‐backend
(i-‐553a519c
on
aws::us-‐west-‐2)
to
be
connectable
-‐
bootstrap-‐backend
is
now
connectable
-‐
generate
private
key
(2048
bits)
-‐
create
directory
/etc/chef
on
bootstrap-‐backend
-‐
write
file
/etc/chef/client.pem
on
bootstrap-‐backend
-‐
create
client
bootstrap-‐backend
at
clients
-‐
add
public_key
=
"-‐-‐-‐-‐-‐BEGIN
PUBLIC
KEY-‐-‐-‐-‐-‐n...SNIP...-‐-‐-‐-‐-‐END
PUBLIC
KEY-‐-‐-‐-‐-‐n"
-‐
Add
bootstrap-‐backend
to
client
read
ACLs
-‐
Add
bootstrap-‐backend
to
client
update
ACLs
-‐
create
directory
/etc/chef/ohai/hints
on
bootstrap-‐backend
-‐
write
file
/etc/chef/ohai/hints/ec2.json
on
bootstrap-‐backend
-‐
write
file
/etc/chef/client.rb
on
bootstrap-‐backend
-‐
write
file
/tmp/chef-‐install.sh
on
bootstrap-‐backend
-‐
run
'bash
-‐c
'
bash
/tmp/chef-‐install.sh''
on
bootstrap-‐backend
[bootstrap-‐backend]
Starting
Chef
Client,
version
12.1.1
Chef
Client
finished,
25/32
resources
updated
in
453.570204517
seconds
-‐
run
'chef-‐client
-‐l
auto'
on
bootstrap-‐backend
- 77. Create and connect to EC2 instance
*
machine[bootstrap-‐backend]
action
converge
-‐
Create
bootstrap-‐backend
with
AMI
ami-‐b99ed989
in
us-‐west-‐2
-‐
create
node
bootstrap-‐backend
at
https://api.opscode.com/
organizations/jtimberman-‐chefconf
-‐
update
run_list
from
[]
to
["recipe[chef-‐server-‐
cluster::bootstrap]"]
-‐
waiting
for
bootstrap-‐backend
(i-‐553a519c
on
aws::us-‐west-‐2)
to
be
connectable
-‐
bootstrap-‐backend
is
now
connectable
- 78. Create the API client and give permission
*
machine[bootstrap-‐backend]
action
converge
-‐
generate
private
key
(2048
bits)
-‐
create
directory
/etc/chef
on
bootstrap-‐backend
-‐
write
file
/etc/chef/client.pem
on
bootstrap-‐backend
-‐
create
client
bootstrap-‐backend
at
clients
-‐
add
public_key
=
"RSA
Public
key
content"
-‐
Add
bootstrap-‐backend
to
client
read
ACLs
-‐
Add
bootstrap-‐backend
to
client
update
ACLs
- 79. Bootstrap like you may have seen...
*
machine[bootstrap-‐backend]
action
converge
-‐
create
directory
/etc/chef/ohai/hints
on
bootstrap-‐backend
-‐
write
file
/etc/chef/ohai/hints/ec2.json
on
bootstrap-‐backend
-‐
write
file
/etc/chef/client.rb
on
bootstrap-‐backend
-‐
write
file
/tmp/chef-‐install.sh
on
bootstrap-‐backend
-‐
run
'bash
-‐c
'
bash
/tmp/chef-‐install.sh''
on
bootstrap-‐
backend
[bootstrap-‐backend]
Starting
Chef
Client,
version
12.1.1
Chef
Client
finished,
25/32
resources
updated
in
453.57
seconds
-‐
run
'chef-‐client
-‐l
auto'
on
bootstrap-‐backend
- 80. machine files
*
machine_file[/etc/opscode-‐analytics/actions-‐source.json]
action
download
-‐
download
file
/etc/opscode-‐analytics/actions-‐source.json
on
bootstrap-‐backend
to
/tmp/stash/actions-‐source.json
*
machine_file[/etc/opscode-‐analytics/webui_priv.pem]
action
download
-‐
download
file
/etc/opscode-‐analytics/webui_priv.pem
on
bootstrap-‐backend
to
/tmp/stash/webui_priv.pem
*
machine_file[/etc/opscode/pivotal.pem]
action
download
-‐
download
file
/etc/opscode/pivotal.pem
on
bootstrap-‐backend
to
/tmp/stash/pivotal.pem
*
machine_file[/etc/opscode/webui_pub.pem]
action
download
-‐
download
file
/etc/opscode/webui_pub.pem
on
bootstrap-‐backend
to
/tmp/stash/webui_pub.pem
...SNIP
-‐
upload
file
/tmp/stash/webui_priv.pem
to
/etc/opscode/webui_priv.pem
on
frontend
-‐
upload
file
/tmp/stash/webui_pub.pem
to
/etc/opscode/webui_pub.pem
on
frontend
-‐
upload
file
/tmp/stash/pivotal.pem
to
/etc/opscode/pivotal.pem
on
frontend
- 82. Wrap-up and takeaways
• Chef Server 12 is totally what you want to use
• Using Chef to build Chef is awesome
• Chef Provisioning makes deploying to EC2 easy
• chef-server-cluster is a full working example
• chef-server-ingredient is a lower level primitive
• (and used by chef-server cookbook, too!)
• Build your own with chef-server-ingredient