Skip to content

Instantly share code, notes, and snippets.

@pydevops
Created February 15, 2018 18:19
Show Gist options
  • Save pydevops/2b5c6c2427540d996c180e67a601708d to your computer and use it in GitHub Desktop.
Save pydevops/2b5c6c2427540d996c180e67a601708d to your computer and use it in GitHub Desktop.
gcp native chef bootstrap method
#!/bin/bash
## Please set run-list and env-name as instance attributes.
### Installs chef, kicks off initial chef run using passed runlist.
CHEF_VERSION="12.21.31"
RUN_LIST=$(curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/run-list" -H "Metadata-Flavor: Google")
ENV_NAME=$(curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/env-name" -H "Metadata-Flavor: Google")
CHEF_USER=terraformci
CHEF_SERVER_URL="https://chef-server:443/organizations/org/"
NODE_NAME=$(curl "http://metadata.google.internal/computeMetadata/v1/instance/name" -H "Metadata-Flavor: Google")
CHEF_DIR="/etc/chef"
CLIENT_PEM=$CHEF_DIR/client.pem
LOGFILE="/var/log/chef-bootstrap.log"
RUNLIST_JSON='/tmp/firstboot.json'
MAX_RETRIES=3
PATH=/usr/local/bin/:$PATH
log () {
echo -e "$@" | tee -a $LOGFILE
}
# log attributes for posterity
log """### System attributes acquired:
CHEF_DIR=$CHEF_DIR
CHEF_VERSION=$CHEF_VERSION
LOGFILE=$LOGFILE
RUN_LIST=$RUN_LIST
ENV_NAME=$ENV_NAME
MAX_RETRIES=$MAX_RETRIES
PATH=$PATH
NODE_NAME=$NODE_NAME
"""
# install the chef-client via generic installer
curl -LO https://omnitruck.chef.io/install.sh && chmod 744 install.sh && ./install.sh -v $CHEF_VERSION
mkdir -p $CHEF_DIR
mkdir -p /var/log/chef
# download the $CHEF_USER.pem from a secured GCS bucket
/usr/bin/gsutil cp gs://gcs-bucket/chef_$CHEF_USER.pem $CLIENT_PEM || exit 1
chmod 644 $CLIENT_PEM
# generate client.rb
log "\n### Writing chef client config..."
clientrb="""
log_level :auto
log_location \"/var/log/chef/chef-client.log\"
environment \"$ENV_NAME\"
chef_server_url \"${CHEF_SERVER_URL}\"
node_name \"$NODE_NAME\"
ssl_verify_mode :verify_none
"""
log "${clientrb}"
echo "${clientrb}" > $CHEF_DIR/client.rb || exit 1
## generate new chef and client.pem
# make sure it is deleted if there is one
knife node show $NODE_NAME -c $CHEF_DIR/client.rb -u $CHEF_USER --key $CLIENT_PEM && knife node delete -y $NODE_NAME -c $CHEF_DIR/client.rb -u $CHEF_USER --key $CLIENT_PEM
knife client show $NODE_NAME -c $CHEF_DIR/client.rb -u $CHEF_USER --key $CLIENT_PEM && knife client delete -y $NODE_NAME -c $CHEF_DIR/client.rb -u $CHEF_USER --key $CLIENT_PEM
knife client create $NODE_NAME -d -f $CLIENT_PEM -c $CHEF_DIR/client.rb -u $CHEF_USER --key $CLIENT_PEM | tee -a $LOGFILE
echo "{ \"run_list\": [\"${RUN_LIST}\"] }" > $RUNLIST_JSON || exit 1
log "Runlist json written."
# cleanup
trap "rm $RUNLIST_JSON" EXIT
# chef first run
log "\n### LAUNCHING chef client FOR THE FIRST TIME ***"
tries=1
while [[ 1 -eq 1 ]]; do
chef-client -j $RUNLIST_JSON -E $ENV_NAME | tee -a $LOGFILE
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
log "\n### ERROR! Chef run failed."
if [[ $tries -le $MAX_RETRIES ]]; then
log "Retrying in 60s"
tries=$((tries+1))
sleep 60
else
log "### Max retries reached. Aborting the Chef Bootstrap process."
exit 1
fi
else
log "\n### Chef run successful!"
break
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment