Writing code isn’t the only skill you need to deliver software, but it might be the most important skill for everyone involved.
Every role involved in delivering and operating modern systems is beginning to use tools to automate their jobs. Instead of having a deployment checklist, you can define each step in code and have it be done for you automatically. Sometimes this is code written in an actual programming language like Python or Java, but it can also be configuration files written in JSON or YAML.
Once you have code you need to make sure that it does what you want it to do. You could run the software and manually verify that it works, but this doesn’t scale well. As your code base grows, the number of test cases grows with it.
That’s why developers write their test cases as code. Over time, teams create a large suite of test cases that they can run to verify changes they’re working on and ensure that their changes haven’t broken any existing functionality.
Version control systems like git record every change made to the code. Having an archive of every change makes it easy to revert to a previous version of the code if problems are found in the current version.
Version control also allows developers to create branches of related changes that are separate from other changes the team is making. Developers can experiment on the code in isolation and merge their changes back into the main branch when they’re ready.
Since code is stored as human-readable text, each change to the code can be highlighted and reviewed by the rest of the team before being accepted. Reviewers can provide feedback and ask questions to improve the changes. This usually happens within your online version control service, such as Github or Bitbucket.
Having a server or service dedicated to automation ties all of your workflows together. Services like Jenkins monitor your source code and when a developer pushes new changes to the code, the service will automatically run your tests to make sure the changes didn’t break anything. If the tests fail, the developer is notified of the failure. If the tests pass, the changes are allowed to be merged into the main branch. When the changes are merged, the service could take the updated code from the main branch and deploy it to your production servers.
Code isn’t very useful until it’s running on someone’s computer. In the past, businesses had to buy expensive servers to run their code and take the time to configure everything manually. With the growth of public clouds like AWS it’s easy to run your code on someone else’s computers. Infrastructure-as-Code tools like AWS CloudFormation and Terraform let you define your infrastructure in a text file and automatically create it in the cloud.
Once your infrastructure is defined, you can create automated tests for your infrastructure using tools like taskcat and terratest. These will create your infrastructure in the cloud, ensure it was successful, and destroy the created resources. You can use a tool like conftest to read your CloudFormation or Terraform code and ensure that best practices are being used.
Run these tests in your automation server to verify every change in your infrastructure before deploying it in production
Once you have a server, the first thing it will need is an operating system. You can use Packer to create an operating system for the server to boot from. It supports formats for all of the major cloud providers. Beyond the operating system you can customize the configuration of your machine image using shell scripts or a more heavy-duty tool like Ansible, Chef, or Puppet. These are helpful for things like adding users, changing passwords, creating SSH keys, etc.
Now you have a fully configured machine image that you can boot your servers from, but like all code, it isn’t complete until it’s tested. Tools like Goss and Chef Inspec can help with that by asserting a criteria against your running servers.
You can codify your security best practices by using a Policy-as-Code tool like Sentinel or Open Policy Agent. Take your security testing a step further using static or dynamic application security testing tools to scan for vulnerabilities. Run these tests in your automation pipelines to ensure your applications and infrastructure are security-compliant
Embracing code at every level of software delivery opens doors to automation, and a commitment to automation will lead to higher quality systems that are created more quickly.