2021-02

# Production-Grade Infrastructure and DevSecOps in Under Five Minutes

This is a story about achieving production grade infrastructure in under five minutes. This is a story about achieving production grade DevSecOps in under five minutes. This is a story about achieving total convergence of GitOps in under five minutes. This is a detailed review of how GitLab's Five Minute Production was built from the ground-up. My name is Sri and over the last three months and I worked closely with GitLab co-founder Dz in building "Five Minute Production". Five Minute Production Diagram Five Minute Production blends solutions offered by AWS, Hashicorp Terraform and GitLab together and offers production-grade infrastructure and development workflows in under five minutes. We start with your GitLab project which has the source code of your web application. Regardless of which language or framework you use, your web application is packaged as a container image and stored within your GitLab project's Container Registry. This is the Build stage. Then comes the Provision stage where Terraform scripts connect to AWS and create a secure environment for your web application. The environments provisioned relate to your Git branching workflow. Long-lived Git branches create long-lived environments, and short-lived Git branches correspond to short-lived environments. Resources provisioned include an Ubuntu VM, scalable PostgreSQL database, a Redis cluster and S3 object storage. We consider these elements as the building blocks for majority of web applications, and many of these fall under AWS free tier. The infra state and credentials are stored within your GitLab project's managed Terraform state. Finally, we have a Deploy stage which: 1. Retrieves the deployable package from the GitLab Container Registry 2. Retrieves the infra credentials from the Gitlab Managed Terraform State, and 3. Proceeds to deploy your web application You get all of this by simply including these two lines in your `.gitlab-ci.yml` file. include: remote: https://gitlab.com/gitlab-org/5-minute-production-app/deploy-template/-/raw/stable/deploy.yml Let's look at the complete process in more detail. Three stages of Five Minute Production

## Build and Package

The Build stage is where it all begins. Five Minute Production reuses the "Auto Build" job from the GitLab Auto DevOps pipeline. Auto Build builds and packages web applications that are: 1. Containerized with a Dockerfile, or 2. Compatible with the Cloud Native buildpack, or 3. Compatible with the Heroku buildpack Thus, web applications across multitudes of technologies are supported, including web frameworks such as Rails, Django, Express, Next.js, Spring etc. and programming languages including Python, Java, Node.js, Ruby, Clojure etc. Once the Auto Build job has finished execution, we have newly created container image stored in your GitLab project's Container Registry as an artifact.

## Provisioning Infrastructure

The next step, Provision, prepares infrastructure resources in AWS. The first requirement here is the presence of AWS credentials stored as CICD variables at the project or group level. Once valid AWS credentials are found, a Terraform script is executed to generate resources in AWS. These resources include: 1. EC2 VM based on Ubuntu 20.04 LTS 2. PostgreSQL database managed by AWS RDS 3. Redis cluster managed by AWS ElastiCache 4. S3 bucket for file storage 5. Email Service credentials managed by AWS SES Out of these resources, the critical resource is the PostgreSQL service, for which we have daily backups enabled. PostgreSQL data is snapshotted if the infrastructure resource is "destroyed" thru a manual user action via the Five Minute Production pipeline. The EC2 VM is the only service accessible publicly. Ports 22, 80 and 443 are exposed. Every other resource described above is part of a secure private network, hidden from the public web, accessible ony via the EC2 instance and your web applicable deployed there. Do note, these are stateful services and the environments are coupled with your Git branches. This means every Git branch creates a new environment with these resource-sets. We don't have a preference on your Git branching and environments life cycle. Use long-lived or short-lived branches as you see fit. Just keep in mind that long-lived branches leads to long-lived environments and short-lived branches leads to short-lived environments. Infrastructure resources provisioned on AWS

## Deploying Your Web Application

Finally comes the Deploy stage. This is where the deploy script retrieves your web application package (container image) from the GitLab Container Registry, then retrieves the EC2 instance credentials from the GitLab Managed Terraform State, and proceeds to deploy the relevant version of your web application in its environment. Do note that modern web application might require additional commands to be execute after each deployment or after the first ever deployment, and these commands can be defined as variables in your `.gitlab-ci.yml` file. Finally, with the help of Certbot from Letsencrypt, SSL certificates are generated and configured for your web application. If you have defined the `CERT_DOMAIN` the SSL certificate will be generated for your custom domain name, else the generated SSL certificate uses a dynamic URL that Five Minute Production prepares for you.

## In Conclusion...

There we have it. A simple yet production-ready setup for your web application. If you are looking for AWS based setup, this is ready for usage. If you are looking for something similar but not quite Five Minute Production, this serves as an example of how to converge infra-as-code with software development and provide seamless continuous deployment workflows. In my personal experience, this is one of the most complete examples of GitOps: 1. Your application source code lives in your GitLab project 2. Your infrastructure defined as code lives in your GitLab project 3. Your CICD pipeline lives in your GitLab project 4. Your infrastructure state lives in your GitLab project 5. Your infrastructure secrets and credentials live in your GitLab project 6. Your environments configuration lives in your GitLab project Finally, do note that this complete GitOps convergence is not specifically configured for one project, but it has been templatized to be consumed across multiple projects. There is no reason why the GitLab project in your organization cannot be the single source of truth for everything.

## Links

* Five Minute Production * Reference Examples

## About the Author

Sri Rangan, an Enterprise Solutions Architect with GitLab, is a core-contributor and maintainer of Five Minute Production.