Software applications these days have gotten more complex than they used to be, and the process of deploying apps has moved from being entirely the job of an IT Operations Team to a collaboration between developers and the IT Team. This collaboration is what we know today as DevOps.
The deployment phase of software is just as important as the development phase and requires just as much thought and planning. This is where a deployment readiness checklist comes in.
A deployment readiness checklist is a comprehensive list of steps and activities involved in the deployment of your application.
Benefits of Having a Deployment Checklist
As applications become more elaborate, so does their deployment. Without a reference to consult, it becomes quite easy to miss a step, which could prove costly down the line. A deployment readiness checklist is an investment with a near-immediate ROI.
Having a deployment checklist in place minimizes the risk of something going wrong or being missed during deployment. Since there’s a process to follow, if all items on the checklist have been checked, you know it should be smooth sailing when getting your app into production.
A deployment readiness checklist helps keep everything on track, not just for first-time deployment but also for subsequent deployments. A thoroughly documented checklist can serve as a guide or reference for new members of the team, minimizing how much they have to rely on someone else’s institutional knowledge and allowing any member of the team to deploy without errors.
Planning for Deployment
The deployment phase of your app is a crucial one and should be well-planned to minimize the chance of errors, conflicts, and other problems. There are many steps to preparing for deployment, and some of the key ones will be discussed here.
- Get all stakeholders and teams involved
Even though deployment is meant to be a collaboration between development and operations teams, it’s important that other major stakeholders are included, as every decision made here impacts the organization as a whole. Employees, business partners, stakeholders, customers, and key decision-makers should be aware of information that’s relevant to them. This can help manage expectations; for example, ensuring that employees and clients know that there may be a brief period of downtime during an upgrade.
- Understand and agree on key performance indicators (KPI)
Before starting deployment, teams should understand and have a system for tracking what the success or failure of the deployment means. Your KPI metrics could include things like downtime during deployment, memory usage, CPU usage, the cost of each deployment, and the number of steps involved.
- Prepare a release versioning and release notes process
Versioning each deployment can help isolate and identify issues. Release notes explain the reason for deployment and can also serve as documentation for future reference.
- Prepare a rollback system
As much as we try to minimize the chance of failure during deployment, it can still happen. This makes a rollback system a key part of your deployment planning. If things get broken after deployment, you’ll want to make it as easy as possible to restore a previous working release.
- Automate as much as you can
The beauty of modern-day deployment is that there are myriad tools available to help you automate your processes. Automating your deployment processes greatly reduces the chance of errors since many things won’t be done manually. Write a script of repeatable steps so you can be sure that everything that should be run is run.
We’ve established why it’s good to have a deployment readiness checklist, but it’s also helpful to see what one might look like. While the checklist here might not entirely apply to you, it’s a good place to start and can be adapted to suit your organization, business, or technology stack.
- Build AMIs (if running on EC2): An Amazon Machine Image (AMI) provides the information required to launch an instance
- Build Docker images: If you’re running your app as containers, package and push your Docker images to the Docker registration
- Configure container orchestration: If you’re deploying your app as containers, a container orchestrator, like Kubernetes, will make it easier to manage your containers.
- Configure VM/host specs, HDD, CPU, and RAM: Configure virtual hosts, hard drives, and CPUs, ensuring your app has sufficient resources
- Set up cron jobs: Configure cron using a tool, like crontab or AWS Lambda Scheduled events, to run background or scheduled events.
- Configure a content delivery network (CDN): CDNs, like CloudFront and Cloudflare, deliver your content to your customer using servers that are geographically closer to them, thereby reducing network latency.
- Configure caching: Making browsers cache your static pages will make loading those pages faster since the browser doesn’t need to make a server request to load them.
- Configure cache busting: While caching is good, content can easily become stale, and you need a system for notifying the browser if an asset should be updated. This is called cache busting. You can achieve this by versioning your files when they’re updated; for example, by changing
- Set up relational databases: This could include MySQL, PostgreSQL, or Amazon RDS as a managed database.
- Set up NoSQL databases: For example, you could set up MongoDB or CouchDB.
- Set up queue systems: This includes services like Amazon SQS, RabbitMQ, and Redis.
- Set up data backup: Usually, database backups aren’t needed—until something goes wrong and you wish you had one in place. Avoid this trap by backing up your data right from the start. You can set up jobs to dump your database at intervals or use tools provided by your cloud service provider to automate the backup process.
- Run schema migration: If your version control schema changes in your code, you’ll be able to easily update your database schema when it changes.
- Set up file storage: Where will files generated during app usage be stored? For example, consider things like files uploaded by users or documents users generate. Configure tools, like Amazon S3, Cloudinary, or Dropbox, to store these files.
- Set up static IP addresses: If you’re using AWS, be aware that all AWS resources use dynamic IP addresses, which means the address can change at any time, making it hard to create systems dependent on them. Use Elastic IP Addresses to get a static IP address.
- Configure DNS: DNS properly routes your server IP address to domain names.
- Create load balancers: Load balancers help distribute network or application traffic across multiple servers, ensuring that servers don’t get overloaded. Use tools like AWS Elastic Load Balancing to load balance across your servers.
- Configure SSL: Set up SSL to encrypt data transmitted between networks. You can obtain an SSL certificate using tools like AWS Certificate Manager (ACM) or Certbot.
- Configure SSH access: You’ll probably have to connect to your server over an SSH connection. Using a terminal like PuTTY, you can access your server remotely to manage it. Keep your SSH connection key pairs secure and remember not to commit these keys to your version control system.
- Check your application against the OWASP Top 10: By running your app against the OWASP Top 10 risks, you’re able to identify common security gaps in your app.
- Perform security audit: Perform vulnerability scanning and penetration testing, which will help you uncover security risks in your codebase or dependencies.
- Set up secret management tools: Poor credential management is one of the top security flaws of any system. Don’t store passwords in plain text; use security managers like 1Password to manage secrets. Do not commit secret keys to your version control system.
Continuous Integration / Continuous Delivery
- Pick a version control system (VCS): Using a VCS like Git and clients like GitHub, GitLab, and Bitbucket make it easy to create deployment pipelines. More importantly, they provide a means of code storage and easy collaboration between multiple developers.
- Check code into your VCS: Your code should be continuously committed into your VCS, which will ensure that you don’t lose changes if anything goes wrong.
- Write and run automated tests: Having automated tests assure you that things work as they should, increasing confidence in your codebase. Automated tests save time since you don’t have to manually test every time you make changes.
- Do code reviews: A code review process should be put in place. Code review adds a human touch and fosters interpersonal relationships; more importantly, it can help catch semantic bugs missed by automated test tools.
- Set up static code analyzers: Static code analysis tools scan your code, format, and lint based on predefined rules. This helps ensure that the code stays in line with current standards.
- Set up deployment environments: Set up different deployment environments, such as a testing server and a staging server. These servers should have a similar configuration to the production server. Apps can be tested on these servers to ensure that when they’re deployed to production, they’ll perform as expected.
- Create a zero-downtime deployment strategy: A zero-downtime deployment is one where existing users don’t experience any disruption during the deployment. This can be achieved in a number of ways; one of which is using load balancers.
- Make sure infrastructure is all stored as code (IAC), not created manually: As mentioned earlier, many parts of your deployment can be automated using different tools and scripts. By using something like GitHub Workflow YAML file, you can define steps and processes that GitHub then runs on certain events, like a push.
Sample GitHub deployment workflow
# Sample GitHub deployment workflow
branches: [ master ]
- uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e
- uses: actions/checkout@v2
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --ignore-platform-reqs
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Create Database
mkdir -p database
- name: Execute tests (Unit and Feature tests) via PHPUnit
- name: Log in to server
sudo git pull
sudo bash deploy-script.sh
Logging and Monitoring
- Configure log management tools: Logs are useful for debugging what has gone wrong with a system at different points in time. You can use a tool like Papertrail to collect and manage logs in your software.
- Configure internal/external monitoring tools: By actively monitoring your deployment process and even your software after the deployment process, you get instant notifications when things go wrong; hence, you are able to fix problems before they become known to your customers. Using tools like Prometheus or Sentry, you can monitor your processes and get error reports in real time.
There are many steps and processes you need to put in place during deployment. That alone should make it clear how important it is to have a well-documented deployment readiness checklist. With a checklist in place, you shouldn’t be afraid to deploy—even on Fridays.
As with other processes, your deployment process and checklist should continue to grow, change, and improve as your team evolves; but the checklist here is a great starting point.
Now, go and deploy!
(A big thank you to Sodeeq Elusoji for his contribution to this article)