Book Image

Automating DevOps with GitLab CI/CD Pipelines

By : Christopher Cowell, Nicholas Lotz, Chris Timberlake
Book Image

Automating DevOps with GitLab CI/CD Pipelines

By: Christopher Cowell, Nicholas Lotz, Chris Timberlake

Overview of this book

Developers and release engineers understand the high stakes involved in building, packaging, and deploying code correctly. Ensuring that your code is functionally correct, fast, and secure is a time-consuming and complex task. Code implementation, development, and deployment can be conducted efficiently using GitLab CI/CD pipelines. Automating DevOps with GitLab CI/CD Pipelines begins with the basics of Git and GitLab, showing how to commit and review code. You’ll learn to set up GitLab Runners for executing and autoscaling CI/CD pipelines and creating and configuring pipelines for many software development lifecycle steps. You'll also discover where to find pipeline results in GitLab, and how to interpret those results. Through the course of the book, you’ll become well-equipped with deploying code to different environments, advancing CI/CD pipeline features such as connecting GitLab to a Kubernetes cluster and using GitLab with Terraform, triggering pipelines and improving pipeline performance and using best practices and troubleshooting tips for uncooperative pipelines. In-text examples, use cases, and self-assessments will reinforce the important CI/CD, GitLab, and Git concepts, and help you prepare for interviews and certification exams related to GitLab. By the end of this book, you'll be able to use GitLab to build CI/CD pipelines that automate all the DevOps steps needed to build and deploy high-quality, secure code.
Table of Contents (18 chapters)
1
Part 1 Getting Started with DevOps, Git, and GitLab
6
Part 2 Automating DevOps Stages with GitLab CI/CD Pipelines
11
Part 3 Next Steps for Improving Your Applications with GitLab

Packaging and deploying code manually

Now that your software has been built, verified, and is secure, it’s time to think about packaging and deploying it. Just like the other steps we’ve discussed, this process can be an annoying burden when done manually. How you package an application into a deployable state depends not only on the computer language it’s written in but also on the build management tool you’re using. For example, if you’re using the Maven tool to manage a Java product, you’ll need to run a different set of commands than if you’re using the Gradle tool. Packaging Ruby code into a Ruby gem requires another, completely different, process. Packaging often involves collecting tens, hundreds, or thousands of files, bundling them with a language-appropriate tool, double-checking that documentation and license files are complete and in the right place, and possibly cryptographically signing the packaged code to show that it’s coming from a trusted source.

We’ve already mentioned the task of specifying which license your code is being released under. This leads to another kind of testing that needs to be done before you can deploy your code to production: license compliance scanning.

License compliance scanning

Most open source, third-party libraries are released under a particular software license. There are countless licenses that developers can choose from, but the bulk of open source libraries use just a handful of them, including the MIT License, GNU General Public License (GPL), and the Apache License. It’s critical to know which licenses your dependencies use because you are not legally allowed to use dependencies that use licenses that are incompatible with your project’s overall license.

What would make two licenses incompatible? Some licenses, such as the Peaceful Open Source License, explicitly prohibit the use of the software by the military. Another, more common cause of license clashes is between so-called Copyleft licenses and proprietary licenses. Copyleft licenses such as the GPL stipulate that any software that uses libraries covered by the GPL must themselves use the GPL license. Copyleft licenses are sometimes called viral licenses because they pass their license restrictions on to any software that uses dependencies that are covered by those types of licenses.

Since you’re legally required to make sure that your main license is compatible with the licenses of any third-party libraries you use, you need to add a license scanning step to your packaging and deployment workflow. Whether this is done manually or with an automated tool, you must identify and replace any dependencies that you’re not allowed to use.

Deploying software

Once your software has been packaged and you’ve double-checked the licenses of your dependencies, you face the hurdle of deploying the code to the right place at the right time.

Most development teams have several environments they deploy code to. Every organization sets these up differently, but a typical (albeit minimal) environment structure might look like this:

  • One or more test environments.
  • A staging environment or pre-production environment that’s configured as similarly to the production environment as possible, but usually much smaller in scale.
  • A production environment.

We’ll talk about the use of these different environments in more detail later, but for now, you just need to understand how each of these environments is used as part of the basic deployment workflow. As code is being developed, it is normally deployed to the test environment so that the QA team or release engineers can make sure it does what it’s supposed to do, and integrates with the existing code without causing any problems. As the new code is declared to be ready to add to the production code base, it is traditionally deployed to the staging environment so that a final round of tests can be made to make sure there are no incompatibilities between the new code and the environment in which it will ultimately run. If those tests go well, the code is finally deployed to the production environment, where real users can benefit from whatever feature, bug fix, or other improvements the new code introduced.

As you might imagine, making sure that the right code gets deployed to the right environment at the right time is a tricky but critically important job. And deploying is just half the battle! The other half is making sure the various environments are available and healthy. They must be running on the right types and scale of hardware, they must be provisioned with the right user accounts, they must have network and security policies configured correctly, and they must have the correct versions of operating systems, tools, and other infrastructure software installed. Of course, there are maintenance tasks, upgrades, and other system reconfiguration jobs that must be planned, carried out, and fixed when they go awry. The mind-boggling scope and complexity of these tasks are why big organizations have whole teams of release engineers making sure everything works smoothly and frantically troubleshooting when it doesn’t.

This completes our tour through the most common SDLC tasks that happen after you’ve checked in the new code:

  1. Build the code.
  2. Verify the code’s functionality, performance, resource usage, and more with a variety of tests.
  3. Make sure the code doesn’t have security vulnerabilities by using even more tests.
  4. Package the code into a deployable format.
  5. Look for and remediate any problems with incompatible licenses.
  6. Deploy the code to the appropriate environment.

By now, you should be sensing a theme: life before GitLab was complicated, error-prone, and slow. These adjectives certainly apply to the package, license scan, and release tasks that occur near the end of the SDLC. But as you’ll learn in more detail in a later chapter, GitLab CI/CD pipelines take care of the most burdensome aspects of these jobs for you. By letting the pipeline handle the boring and repetitive stuff, you can concentrate on the more creative and satisfying parts of writing software.