Towards AIblog

Terraform vs CI/CD for Serverless Deployments

Monday, May 18, 2026Simon CordeView original
Last Updated on May 19, 2026 by Editorial Team Author(s): Simon Corde Originally published on Towards AI. I passed the Terraform certification some month ago. While learning terraform, I quickly found myself willing to provision all I can through terraform. Turned out a bad idea. Here is why. Do you use Terraform for deploying helm charts ? Terraform vs CI/CD for Serverless Deployments 1. The confusion between infra and app lifecycle Infrastructure lifecycle and application lifecycle differ Infrastructure change slowly whereas application releases can appear multiple times a day. For instance, while you are satisfied with your network configuration, you will not change it much at during next year. On the other hand, if your release of this morning for your application has broken some feature despite all the tests you have put in place, you want to rollback to the previous version quickly. Therefore the changes you make to application have to be released much more frequently than pure infrastructure. You cannot handle both in the same place. 2. What Terraform is GREAT at Terraform is an open source Infrastructure As Code open source tool created by Hashicorp. It allows to define your infrastructure, provision and manage it. It has seen a huge adoption in the industry though the years. It allows you to automated deployment for different providers, namely the cloud ones like AWS, Azure, GCP but also other PaaS like Heroku or even github or gitlab. Today many tools have their Terraform provider to allow you to declare your configuration in files and communicate with their apis. The 1 M$ question really is what do I put in Terraform ? Terraform shines at defining your desired state in terms of configuration for the following: networking IAM buckets SQL data base secrets DNS load balancer These infrastructure components define the core of your systems. Once they are setup, you rarely update them. 3. Why application deployment is different Over the past few years, the tech industry has become significantly more competitive. And this shift has only accelerated with the arrival of AI-powered coding assistants. Today, development velocity is no longer a nice-to-have β€” it is a core requirement. Feature teams can no longer afford to wait weeks or even a full month to deliver new functionality. In many organizations, it is now common to ship multiple features per week, and in some cases, even multiple times per day. This level of speed requires a fundamental change in how software is delivered. Promoting application images across environments must be fast, reliable, and fully automated in order to support rapid testing and release cycles. Equally important is the ability to roll back just as quickly when something goes wrong. In this model, deployment is no longer just about pushing changes to production β€” it is about enabling continuous, safe, and reversible delivery at high velocity. 4. The Cloud Run example Let us take as a backbone example the serverless platform in Google Cloud named Cloud Run. This is a container as a service platform which can run at scale. We are going to compare the workflows to deploy an application through Terraform vs through Continuous Deployment leveraging github actions. πŸ’‘All material found in this article can be found in my repository at https://github.com/Redcart/serverless-deployment. πŸ›  Terraform example In the following piece of Terraform configuration, we are defining our cloud run service. Once you are satisfied with this configuration, you just need to run terraform apply. But now, if you need to promote a new version of your app ? You first need to build and push the new docker image of your code in Artifact Registry. Second you have to pick up the righ name and change it in the variable named below container_image. Eventually run terraform apply. resource "google_cloud_run_v2_service" "cloud-run-service" { name = var.cloud_run_service_name location = var.region ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" deletion_protection = false template { service_account = var.sa_cloud_run containers { image = var.container_image env { name = "GCP_PROJECT_ID" value = var.project_id } env { name = "INPUT_DATASET" value = var.input_dataset } env { name = "OUTPUT_DATASET" value = var.output_dataset } env { name = "API_KEY" value_source { secret_key_ref { secret = var.api_key_secret_name version = var.api_key_secret_version } } } } }} πŸ›  CI/CD in github actions example In the following piece of configuration code, we are deploying through gcloud CLI in github actions a cloud run service. If we want to deploy a new version of the app, we just have to commit and push the change in the github remote repository, Then the CI/CD will be triggered, the docker image built and pushed to Artifact Registry, the cloud run service automatically updated with this new docker image. All in one step, from one single repository. IMAGE=${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.GCP_PROJECT_ID }}/cloud-run/app:${{ github.sha }}gcloud run deploy ${{ env.PROJECT }} \ --image=$IMAGE \ --region=${{ env.GCP_REGION }} \ --platform=managed \ --memory=1Gi \ --no-allow-unauthenticated \ --ingress=internal-and-cloud-load-balancing \ --service-account=${{ env.SERVICE_ACCOUNT_RUNTIME }} \ --set-env-vars GCP_PROJECT_ID=${{ env.GCP_PROJECT_ID }} \ --set-env-vars INPUT_DATASET=${{ env.INPUT_DATASET }} \ --set-env-vars OUTPUT_DATASET=${{ env.OUTPUT_DATASET }} \ --set-secrets API_KEY=API_KEY:latest 5. Terraform pain points for deployments While we have seen in the previous section that deploying a cloud run service through terraform can be easy, it has some limitations. First, as discussed earlier, it mixes infra and app concerns. In some teams, people in charge of infra and app are not the same. You can encounter lack of velocity especially if you need to quickly rollback because of a pending apply (a colleague has done a plan but has not confirmed the apply yet). You can ran into state locking, drift is more likely to happen and interfer with the behavior of your app in production. The plan of such terraform workspaces can become very noisy and take a while. πŸ“Œ To overcome some of these limitations, one may tempted to say ok, I will have more terraform workspaces to not be bothered by other pending apply or long plan. But here again, do not underestimate the complexity and challenge to maintain a bunch of workspaces. […]