I've been looking to improve my deployment game in the hopes of getting to a point where I would just push my changes and a new version would fall out on the other side. Additionally I wanted to be able to set up a new project complete with pipeline, domain etc. in no time. This quest has led me to my current setup.
There are three layers:
I create a new repository in github using github cli. Depending on the project I start by building out some core functionality and test locally. When the core logic is in place, I create a dockerfile and copy over the github actions pipeline which is somewhat standardized across repos. It checks out the code and increments the version in package.json or equivalent. Then it builds the docker image and pushes it to GitHub Container Registry (GHCR). Finally, it checks out the corresponding application manifest in the app-of-apps repo to update the image with the new version there. Once that's through, ArgoCD picks up the version change, pulls the new image, and spins it up in my Kubernetes cluster. All while having zero downtime.
The application manifest looks essentially the same for all my applications. It points to a dedicated folder in the app-of-apps repo which holds the deployment manifest and everything else that's needed (service, ingress, pvc, etc.). The agent can generate those beautifully when given one of the existing applications as a template.
Looking at this high level picture I am quite happy with how it works. It's definitely an improvement over my previous setup where I was sshing my code to my server and triggered a docker compose build && docker compose up there.
Let's now look at the areas which still cause some friction. I recently moved my terraform state file from my local computer to an S3 bucket. In and of itself this is nice but it introduced some hurdles regarding permissions. For security I don't wan't my CI role to be able to change its own permissions. This means that whenever I add a new SSM parameter path for a new application I need to locally run terraform apply with the updated permissions on the CI role. This is a bit of a pain but I suppose it's manageable.
Once the role permissions are updated, the ssm part works smoothly. I have the agent create the required parameters and then simply write my secrets to them once.
One of the things I do quite often currently is setting up new website projects. As of now I still need a few prompts to set those up. I'm thinking I could formalize what I've written above in a skill to get a website created, up and running in one shot.
Creating a simple website from a single prompt has proven to work well even with a open weights model like Kimi-K2.5. Once I get the deployment context well specified I should get close enough to one-shotting a website.
What are the manual tasks in my current workflow?
terraform apply locally to update the CI-rolesThis journey has taught me that the last item is often the hardest part. Once you have the technical scaffolding in place, the real work becomes clarifying your vision and purpose.
I've formalized this entire process into a reusable skill. The goal is one-shot website creation: describe what you want, and the system handles repository creation, CI/CD pipeline setup, Kubernetes manifests, DNS configuration, and deployment. With only two manual steps remaining (terraform apply and GitHub secrets), we're remarkably close to that goal.
What a time to be alive.