Deploying your software
Deploying software should be treated just like your infrastructure; repeated deployments of the same commit and the same configuration should yield a consistent state of your environment. In this example, we will be able to deploy new updates to our web application simply by updating any nodes that use the web_server
role. The combination of our recipe and our configuration data with the source code hosted in our GitHub repository will ensure that the most up-to-date configuration and source are placed on our host.
Manually deploying updates
Future deployments only require pushing changes to the master branch and then running chef-client
on any web servers that are in the fleet. This can be accomplished on a single host (web00
) using the following command:
knife ssh 'name:web00' -x ubuntu 'sudo chef-client'
This will tell knife
that we want to SSH to the host whose name is web00
as the ubuntu
user (because that's the default EC2 user with sudo
access) and execute chef-client
as root
via sudo
. This will work well if we only have one host; however, as your capacity increases and you have multiple hosts, you will likely want to execute this on a group of hosts in the future. This can be accomplished using the search capability of Chef that allows you to expand a list of nodes that match a set of criteria. Here, we will want to build a list of all the hosts that have our web_server
role associated with them. The following command will accomplish this:
knife ssh 'role:web_server' -x ubuntu 'sudo chef-client'
This will use Chef's search to find all nodes with the web_server
role and then SSH to them sequentially, the same as before but only across multiple hosts instead of just one.
Automating deployment
The web application recipe is designed so that it syncs the source with the upstream GitHub repository. By doing this, we can execute the recipe multiple times, and any time there are updates, they will be pulled down onto the local host. If we wanted to, the process of deployments could be automated in the following fashion:
- Active development of the application happens in a separate, development branch
- Code is tested thoroughly and then merged into a master (or whatever branch is being deployed onto hosts) when it is stable and ready for production
- Hosts are configured to run
chef-client
on a fixed interval using a tool such ascron
and will automatically update themselves
The possible issues with this are that bad code gets automatically deployed to endhosts and so on. However, with enough integration testing and a high enough confidence level, our code should be safe to deploy to production if it is in the master branch. Through a combination of tags and proper source management, rollbacks could be as simple as reverting the deploy branch to a known-good tag and they would happen as soon as the next chef-client
execution or forced using knife
as outlined previously.