A while back, I started migrating my CD to a full GitOps process. I wanted my developers to have their code deployed to the environment of their choice without involving me. As a single DevOps engineer, I also wanted them to depend less on me and have the CD functioning on its own.
As part of that migration, I replaced my Pulumi deployment to K8S with Helm and ArgoCD, but one issue remained: what to do with my AWS resources that Pulumi had been deploying up until then?
Automation was the first thing on my mind. I needed some sort of IaC, but one I could control using Git, to match my current GitOps flow, that would shift the changes with a single commit to my leading repository’s branch. To clarify, GitOps is a deployment method that, at its core, consolidates all changes to the applications and infrastructure using the code committed to Git. These changes are automatically picked into your environment by various tools (such as ArgoCD). This means that your Git repository, and chosen branch, is the one source of truth for your applications and infrastructure. In my opinion, this is awesome and makes life a lot easier when it comes to deployments, state management, and rollbacks.
During my search, I came across Crossplane—an open-source tool introduced back in late 2018 but which has really gained traction in the last couple of years. Basically, Crossplane lets you manage every infrastructure object through the K8S API using CRDs. This was a perfect match for me as I could now manage my AWS resources—my IAM roles, SQS queues, S3 buckets, etc.—using my Helm charts. All of these could be deployed using Argo directly to my K8S clusters and, using the Crossplane controllers, then to my AWS environments.
Creating Connection between Crossplane, EKS and AWS
I’m going to describe an implementation of a simple scenario when we want to deploy an IAM role to AWS from our K8S API.
prerequisites:
- An EKS cluster.
- AWS account with an IAM role for Crossplane to use to create resources
Installing Crossplane:
I installed Crossplane using the official helm chart in a dedicated Crossplane repo:
After installation, you will see many API resources being generated.
kubectl api-resources | grep crossplane
Authenticating:
As for security, Crossplane offers authentication using both IRSA (IAM Role for Service Accounts) and WebIdentity authentication, in addition to less secure options which I will not elaborate on.
Because I am currently using IRSA for most of my services, let’s describe how to make it work with Crossplane. The general idea is the same as making IRSA work for any other application; we need to connect the IAM role we’ve created to our Crossplane service account.
This is what my role's trusted entities look like:
This trusted entities section allows Crossplane to assume my role and use its credentials.
Next, we’re going to create the following resources:
- ControllerConfig: Describes the configuration of a specific Crossplane controller.
- Provider: Describes a Crossplane package to install, in our case IAM. Crossplane providers exist for various cloud services; all providers can be found here.
- ProviderConfig: Describes the configuration for a specific provider. In our case, the authentication method will be detailed here per provider.
Let’s get started with credentials, creating the ControllerConfig for our IRSA authentication. You’ll note that we are specifying the ARN of the role we created in the AWS account for Crossplane to use.
Run the following command to apply it to the cluster:
kubectl apply -f irsa-config.yaml -n crossplane
After creating the IRSA configuration, let’s create our AWS IAM provider and configure it to use IRSA:
Run this to apply:
kubectl apply -f aws-iam-provider.yaml -n crossplane
Now we can create IAM objects and let Crossplane run its magic and translate those K8S resources into AWS resources.
Apply the role:
kubectl apply -f crossplane-role.yaml -n crossplane
A few seconds after, a brand-new role will be created in AWS.
Considerations When Creating AWS Resources Using Crossplane
These days, all my AWS resources are created using Crossplane. This allows me to bundle applications with their AWS identities automatically and enables quick deployments and rollbacks for both my code and my infrastructure. When using Infrastructure as Code (IaC), here are the main considerations to keep in mind:
- Security: Ensure your credentials and secret information are not exposed or committed to version control.
- Complexity: Choose a tool that simplifies management rather than making it more complicated than creating the components manually.
- Compatibility with your technological stack: Each tool has its own purpose. Make sure the one you choose integrates well with the other tools and cloud providers you work with.