-
-
Save ccooper21/4439163 to your computer and use it in GitHub Desktop.
bash -c ' | |
<%= "export http_proxy=\"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] -%> | |
exists() { | |
if command -v $1 &>/dev/null | |
then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
sudo sed -i "s/\(Defaults[[:space:]]*secure_path[[:space:]]*=[[:space:]]*\)\(.*\)/\1\/usr\/local\/sbin:\/usr\/local\/bin:\2/g" /etc/sudoers | |
if ! exists gcc; then | |
sudo yum -y install gcc gcc-c++ make | |
fi | |
if ! exists git; then | |
yum -y install git | |
fi | |
install_sh="http://opscode.com/chef/install.sh" | |
version_string="-v <%= chef_version %>" | |
if ! exists /usr/bin/chef-client; then | |
if exists wget; then | |
bash <(wget <%= "--proxy=on " if knife_config[:bootstrap_proxy] %> ${install_sh} -O -) ${version_string} | |
else | |
if exists curl; then | |
bash <(curl -L <%= "--proxy=on " if knife_config[:bootstrap_proxy] %> ${install_sh}) ${version_string} | |
fi | |
fi | |
fi | |
mkdir -p /etc/chef | |
( | |
cat <<'EOP' | |
<%= validation_key %> | |
EOP | |
) > /tmp/validation.pem | |
awk NF /tmp/validation.pem > /etc/chef/validation.pem | |
rm /tmp/validation.pem | |
chmod 0600 /etc/chef/validation.pem | |
<% if @chef_config[:encrypted_data_bag_secret] -%> | |
( | |
cat <<'EOP' | |
<%= encrypted_data_bag_secret %> | |
EOP | |
) > /tmp/encrypted_data_bag_secret | |
awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret | |
rm /tmp/encrypted_data_bag_secret | |
chmod 0600 /etc/chef/encrypted_data_bag_secret | |
<% end -%> | |
<%# Generate Ohai Hints -%> | |
<% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%> | |
mkdir -p /etc/chef/ohai/hints | |
<% @chef_config[:knife][:hints].each do |name, hash| -%> | |
( | |
cat <<'EOP' | |
<%= hash.to_json %> | |
EOP | |
) > /etc/chef/ohai/hints/<%= name %>.json | |
<% end -%> | |
<% end -%> | |
( | |
cat <<'EOP' | |
<%= config_content %> | |
EOP | |
) > /etc/chef/client.rb | |
( | |
cat <<'EOP' | |
<%= first_boot.to_json %> | |
EOP | |
) > /etc/chef/first-boot.json | |
<%= start_chef %>' |
I stripped down the list of additional packages to install via "yum" to just "gcc", "gcc-g++", and "make". These are sufficient to get the Chef client installed and execute the recipes that I am currently using. I did find this article, http://wiki.opscode.com/display/chef/Installing+Chef+Client+and+Chef+Solo, that suggests the minimal dependencies also include the "autoconf" and "automake" packages. This dependency list is for installing the Chef client as a Ruby gem though instead of via the omnibus installer. Also, I haven't found a reason to install any packages for development libraries, as was the case in the bootstrap script from which I started, so I removed them. The Chef recipes I am using seem to know which libraries on which they depend and hence install the necessary libraries as needed.
Regarding the addition of the "/usr/local/bin" directory to the path used by the "sudo" command, this is no longer necessary with the cookbooks I am using since the v1.2.0 release of the Python cookbook. The addition of this directory to the path was a partial workaround for issue COOK-1866 (see http://tickets.opscode.com/browse/COOK-1866) fixed in this release.
I'm guessing this may still prove necessary for other cookbooks though. In the event that I keep this statement, it really should be split into two statements, one each for the "/usr/local/sbin" and "/usr/local/bin" directories, and each statement should be made idempotent.
What is this?
This is a Chef bootstrap script for bootstrapping the Chef client on an Amazon Linux AMI instance. It has been tested with Amazon Linux v2012.09 (AMI ID ami-1624987f).
How do I use it?
knife ec2 server create -I ami-1624987f -f t1.micro -G ssh-only -i .chef/aws-master-key.pem -S master-key -x ec2-user -d amazon-linux-omnibus
Why does it exist?
I didn't find Chef to support Amazon Linux well out-of-the-box. Specifically, I encountered several problems:
In addition, while others have posted similar bootstrap scripts, the ones I found all installed Chef as a Ruby gem. Since I am not doing any Ruby development, am not planning to extend Chef beyond the use of recipes and cookbooks, and don't care to build and install Chef's dependencies, I prefer to use the Chef client omnibus installer which bundles together the Chef client and its dependencies.
Contributions
Most of the credit for this bootstrap script goes to others. It was cobbled together based on the "chef-full.erb" and "centos5-gems.erb" scripts included with Chef. It also includes snippets from the Ruby gem based Amazon Linux AMI script found at https://gist.github.com/1571189.
Outstanding Questions and Issues
I'm unclear on the best practices with respect to installing "gcc" and the like. On one hand, it seems like "gcc" should be installed using a Chef recipe. On the other hand, it seems like Chef community cookbooks expect that certain base tools are always available. While this appears to include "gcc", I don't know where this is documented.
I was expecting this same bootstrap script to work with the RightScale Centos v6.3 AMI (AMI ID ami-3b7bfc52) since Amazon Linux is based on Centos. However, it fails on this statement:
sudo sed -i "s/(Defaults[[:space:]]secure_path[[:space:]]=[[:space:]])(.)/\1/usr/local/sbin:/usr/local/bin:\2/g" /etc/sudoers
The failure is a result of a string substitution the "knife ssh" command performs that adds a "-p" option to this occurrence of the "sudo" command. As of Chef v10.16.2, the code that makes this string substitution can be found in the "chef/knife/ssh.rb" file and is as follows:
command.sub(/^sudo/, 'sudo -p 'knife sudo password: '')
I have not yet figured out why the resulting behavior is different on Amazon Linux vs. Centos. As a workaround, white space can be inserted before the "sudo" command causing the regular expression for the string substitution to not match.
While not a Chef issue, I am wondering what the best practice is around installing tools from packages vs. source code. I specifically ran into this with respect to the Python interpreter as the Amazon Linux AMI includes Python v2.6.x while I am deploying an application built on Python v2.7.x. While I believe the Amazon Linux package repository includes a Python v2.7.x package, installing it breaks "yum" since "yum" expects certain non-default libraries (i.e. eggs) to be installed. Building Python v2.7.x from source and installing it in the "/usr/local/bin" directory allows both versions of Python to co-exist and keeps "yum" working. Is this the right thing to do?
Disclaimer / Feedback
My past experience with Linux has been as a super user running Linux on a few nodes for development purposes as opposed to my current assignment as an administrator managing Linux across many nodes in both pre-production and production environments. I am also new to Chef. Hence, I am especially interested in feedback letting me know where I am on-track and off-track. Details are appreciated.