April 12, 2026
Alright, ladies and gentlemen, today is hands-on. We will learn how to set up a CI/CD pipeline using GitLab and deploy a sample application to AWS with short-term credentials. This is the absolute best practice, so if you’ve ever wondered how CI/CD pipelines work between a version control system and a cloud provider, now is your chance to learn.
Our agenda today consists of three simple steps.
Set Up a Sample Project
Build the Pipeline
Create a Federated Identity in AWS
We will allow our GitLab Runner to deploy directly to AWS without the use of long-term credentials of any kind. This setup is as secure as it can get, and hijacking it is impossible.
Static website. Simple and easy. Done, next.
This one can be tricky if you’re new to it, especially when you don’t have someone to guide you. The internet can be helpful, but let’s be real: if you’ve never seen a production pipeline, it’s hard to know what to include.
I’ll keep this step simple, though. The details of a production pipeline are a whole other topic, and covering it fully would take a lot of explanation. For now, just remember that setting up a production-ready CI/CD pipeline usually involves the following steps:
Validate
This step involves linting the code, checking for common build or compile errors, and verifying that the formatting is correct.
Build
In this step, you build the artifact you plan to deploy and store it in your version control system.
Test
While a dedicated team should always do an additional quality assurance step, it’s also important to test early in your lifecycle. This allows you to catch errors early, before they reach the development environment.
Deploy to staging
Deploy to production
The last two steps are where it gets tricky. This is also the key problem when you want to deploy to a cloud provider. Of course, you could use your access keys, but that’s a security risk I do not recommend you take. If someone gets a hold of your access keys, he can do whatever he wants to your servers. And GitLab is certainly not the appropriate place to store them.
The next step is where the real deal begins. We will create the federated identity in AWS from which your GitLab pipeline will request the short-term credentials. And before we begin, I want to highlight how incredibly smart this solution is. AWS has no access to your GitLab, and vice versa. On top of that, there are no long-term credentials stored in GitLab. There is not a single secret key or password you have to manage. AWS STS manages everything for you, and setting up the federated identity in AWS is easier than building the actual pipeline. Here is how it goes.
Create an identity provider in AWS under IAM > Identity providers.
Create a role in AWS under IAM > Roles to associate with the identity provider with.
Establish a trust relationship in your newly created role.
Create a policy that includes the necessary permissions for your pipelines, following the Principle of Least Privilege. Then, attach this policy to the role you created in step 2.
It looks more complex than it is. Trust me, once you get past the basics of “What is AWS STS?” and “How do I set up a policy in AWS?”, it’s actually pretty simple. When you know how to use policies inside out, the only thing left to figure out is what the trust relationship does in step 3.
This trust relationship specifies a few important things. It is a JSON document that defines the identity provider it is associated with, as well as the GitLab repositories that are allowed to use this role. This means all permissions are handled directly inside AWS. You define which repositories can use the short-term credentials provided by AWS STS by specifying your project URLs exactly. Since there is no password, it is impossible to crack.
I know what you probably think by now. You see a JSON document and you shit your pants because of all the Azure ARM templates you have had to see in your life. But don’t worry. This trust relationship is a simple 10-30 line document with only a few parameters you have to adjust for your pipeline to work. If you want to learn more about how to create this trust relationship, I highly recommend this blog post from AWS.
The pipeline works, and there’s not much more to do. Depending on the project and customer, you’ll likely add more steps to your CI/CD pipeline as things progress. However, it’s best to keep your pipeline from getting too bloated and only add steps for a good reason.
The point I’m making is that DevOps engineers shouldn’t just create a huge pipeline and stop there. The pipeline also needs to be maintainable, and I want to emphasize that. If there’s no good reason to have more than five jobs, then don’t do it. Your goal is to build a pipeline that someone else can easily read and understand, even if they’ve never worked on the project before. They should be able to get it without you having to explain it. If your pipeline isn’t like that, then you’ve failed.
Simplicity, clarity, and sustainability are key ingredients in every project.