How to deploy Applications within Projects in Argo CD

Illustration of a cheerful cartoon octopus wearing an astronaut helmet next to a human diver swimming underwater among stylized coral reefs. Illustration of a cheerful cartoon octopus wearing an astronaut helmet next to a human diver swimming underwater among stylized coral reefs.

We have an Argo CD up and running. We have repositories with the code we want to deploy, and we clusters we want to deploy to. The final step is to map which repositories should be deployed to which clusters - and for this we need to learn what Projects and Applications are.

Projects are the top level grouping of applications, and each application belongs to only one project. There is already a default project in here, but let’s create a new one. It’s up to you how to configure projects and applications - you can structure them in any way that works for your organization. In this course, I will create 1 Project per environment - I can, if I want, restrict which users and teams have access to which project. Let me create a “production” project.

Screenshot of the Argo CD web interface with a 'New Project' dialog open, displaying fields for 'Project Name' and 'Description' filled with 'production' and 'Deploys production applications', respectively.

The next step is to configure which repositories are allowed to be deployed within this project. I can specify a wildcard, allowing any repositories, or I can specify concrete repos - let me pick the PGAdmin Helm Chart that we’ve added in the previous lesson.

Screenshot of the Argo CD web interface showing project settings with source repository information, project summary, and options to add roles, sync windows, or delete the project.

Next I can specify which clusters are allowed for this project. I will specify the production cluster, and allow all the namespaces within this cluster. I am not going to create any new roles for this project, neither I will dive deep into sync windows for now. Instead, let’s add an application.

Screenshot of an Argo CD application interface showing settings for 'production' with no source repositories and a destination specified, including a URL and namespace details.

I will name this application simply “pgadmin”, and I want it to be part of a production project. If I want to deploy the same code to multiple environments or clusters, I need to create multiple applications, either within the same project or in different projects - depending on how I decided to structure my Argo CD installation.

Screenshot of Argo CD web interface v2.5.7 displaying an application creation dialog with fields for 'Application Name' and 'Project Name', and various sync policy options.

I will select a “Manual” Sync Policy - it means that I need to click a button to actually deploy anything. I also want to create a namespace automatically. There are a couple of other options in here, but let’s proceed to specifying the code for this repository. I am choosing the pg admin helm chart, and I need to specify that the code is located at the root of the repo. I need to tell Argo CD that this is a Helm application, and I can specify which values file to use - it will pick up the default values file automatically, and on top of this I want to use the production values file. Let me click on create.

Screenshot of the Argo CD user interface showing an Application Details Tree with various resources related to 'pgadmin' in different states like 'OutofSync' and 'Missing'.

Argo CD detects that none of the resources within this repository exist in my Kubernetes cluster. When I click on the application tile, I see one of the nicest parts of the Argo CD interface - a list of all the Kubernetes resources within this application, together with its interdependencies and synchronization status.

I can examine the diff - Argo shows me in a nice way what exactly it will apply during the deployment. If I am happy with this diff - and I am happy - I can click on Sync button, and, leaving most of the sync options unchanged, proceed with the deployment.

Screenshot of Argo CD user interface showing application details with 'OutOfSync' status and synchronization options panel for updating application manifests from a GitHub repository.

Unfortunately, it did not work as I expected - according to the error message, create Namespaces is not allowed in this project. That’s because I did not whitelist any of the Kubernetes resource types in my project configuration. Let’s do that.

A screenshot of the Argo CD application interface showing a failed sync operation with error messages and synchronization task details.

I am going to the project configuration and my plan is to allow any resource types. In some cases, you want to restrict this - for example, maybe you don’t want to allow creation of Ingress objects within this project, or you only want to allow a handful of default object types. Now let me go back to our app and try to sync again.

Screenshot of Argo CD web interface showing application details with a topology map of services, deployments, and pods in a running state within a software deployment process.

Now something really beautiful happens - we can see how Argo CD creates all the resources, and then automatically discovers all the related objects, like replica sets and deployments, and a post-upgrade Job. None of this is part of our Helm Chart, but the tool is smart enough to figure it out and give us some really nice interface. Of course, we are not supposed to spend too much time clicking around the UI, but when we have to do it, it’s good to have such a nice interface. I can even see the logs of the pods, as well as switch between different views for my objects. It even shows me some resource consumption metrics!

A computer terminal screen with text displaying various command line instructions and outputs related to Kubernetes operations, including `kubectl` commands for Argo CD.

Our first Argo CD application is up and running. All of the configuration we just did is just Kubernetes objects - let’s quickly confirm that in our shell. We can store all of this configuration as YAML definitions and, well, deploy them with a Git Ops approach!

But what happens when we change our resources manually? And what happens when we push a change to the repository? That, as well as synchronisation options and windows, will be the topic of the next lesson.

Here' the same article in video form for your convenience: