|
| 1 | +--- |
| 2 | +slug: argocd-commit-pinning |
| 3 | +title: Production Release With Argo CD - Commit Pinning |
| 4 | +description: Gitploy provides another solution deploying to multiple environments. |
| 5 | +tags: [GitHub Action, Argo CD, Commit Pinning] |
| 6 | +image: ./demo.gif |
| 7 | +keywords: [argocd, argo-cd, commit pinning, deployment strategy] |
| 8 | +--- |
| 9 | + |
| 10 | +## Deployment Strategy of Argo CD |
| 11 | + |
| 12 | +[Argo CD](https://argo-cd.readthedocs.io/en/stable/) is the most popular GitOps tool for Kubernetes. Argo CD makes it easy to define an application with its desired state in a repository and where it should be deployed. After a deployment, **Argo CD constantly tracks updates to branches, tags, or pinned to a specific version of manifests at a Git commit.** |
| 13 | + |
| 14 | +Argo CD provides [several different ways](https://argo-cd.readthedocs.io/en/stable/user-guide/tracking_strategies/) of tracking Kubernetes resource manifests. Among them, **commit pinning is typically used to control production environments.** Since commit SHAs cannot change the meaning, the live state of an application can be fixed and predictable. So the application remains stable. |
| 15 | + |
| 16 | +- HEAD / Branch Tracking |
| 17 | +- Tag Tracking |
| 18 | +- Commit Pinning |
| 19 | + |
| 20 | +## Commit Pinning By CLI |
| 21 | + |
| 22 | +Now, we'll deploy the manifest in a specific commit from the Argo CD. First, before starting the demo, install the `argocd` command. More detailed installation instructions can be found via the CLI [installation documentation](https://argo-cd.readthedocs.io/en/stable/cli_installation/). |
| 23 | + |
| 24 | +The [repository](https://github.com/gitploy-io/argocd-demo) to be used as a demo has Kubernetes resources manifests under the `app/` directory and it is customized through [`kustomize`](https://kubectl.docs.kubernetes.io/guides/introduction/kustomize/) for each environment. |
| 25 | + |
| 26 | +<details> |
| 27 | +<summary>File Structure</summary> |
| 28 | + |
| 29 | +```shell |
| 30 | +app |
| 31 | +├── base |
| 32 | +│ ├── deployment.yaml |
| 33 | +│ └── kustomization.yaml |
| 34 | +└── overlays |
| 35 | + ├── dev |
| 36 | + │ └── kustomization.yaml |
| 37 | + └── prod |
| 38 | + └── kustomization.yaml |
| 39 | +``` |
| 40 | + |
| 41 | +</details> |
| 42 | + |
| 43 | +First, we should create an Application for Argo CD: |
| 44 | + |
| 45 | +<details> |
| 46 | +<summary>Create App</summary> |
| 47 | + |
| 48 | +```shell |
| 49 | +argocd app create argocd-demo-prod \ |
| 50 | + --repo https://github.com/gitploy-io/argocd-demo.git \ |
| 51 | + --path app/overlays/prod \ |
| 52 | + --dest-server https://kubernetes.default.svc \ |
| 53 | + --dest-namespace argocd \ |
| 54 | + --sync-policy automated |
| 55 | +``` |
| 56 | + |
| 57 | +</details> |
| 58 | + |
| 59 | +We should change the Application's revision to the commit SHA. At the same time, we also update the image tag with commit SHA: |
| 60 | + |
| 61 | +<details> |
| 62 | +<summary>Update App</summary> |
| 63 | + |
| 64 | +```shell |
| 65 | +argocd app set argocd-demo-prod \ |
| 66 | + --revision COMMIT_SHA \ |
| 67 | + --kustomize-image gitployio/argocd-demo=gitployio/argocd-demo:sha-COMMIT_SHA |
| 68 | +``` |
| 69 | + |
| 70 | +</details> |
| 71 | + |
| 72 | +Finally, We should synchronize the desired state to the Kubernetes cluster: |
| 73 | + |
| 74 | +<details> |
| 75 | +<summary>Sync App</summary> |
| 76 | + |
| 77 | +```shell |
| 78 | +argocd app sync argocd-demo-prod --timeout 300 |
| 79 | +``` |
| 80 | + |
| 81 | +</details> |
| 82 | + |
| 83 | +Then, Argo CD continuously synchronizes the manifest of the commit. As a result, the desired manifest and the live state of Kubernetes are always synchronized. |
| 84 | + |
| 85 | +## Integration With Argo CD |
| 86 | + |
| 87 | + |
| 88 | + |
| 89 | +Commit pinning is appropriate for production environments, but changing revisions every time is difficult. As a result, many teams (or organizations) adopt HEAD/branch tracking because it is much easier than the commit pinning. |
| 90 | + |
| 91 | +But the good thing is that Gitploy can solve this problem easily. Gitploy provides the way to deploy a commit easily, and the deployment event, which is dispatched to CD tooling, includes the commit SHA value. So the CD tool will be able to execute `argocd app set` command with the commit SHA from the deployment event. |
| 92 | + |
| 93 | +Below is an example of a pipeline built with Gitploy and GitHub Actions. When Gitploy deploys a commit, it passes the payload including the Application name of the Argo CD to be deployed, and The GitHub Action pipeline accesses `github.event.deployment.payload` to get the Application name. Also, the GitHub Action pipeline gets the commit SHA through the `github.sha` value to deploy. |
| 94 | + |
| 95 | +<details> |
| 96 | +<summary>Gitploy Configuration</summary> |
| 97 | + |
| 98 | +```yaml |
| 99 | +envs: |
| 100 | + - name: dev |
| 101 | + auto_merge: false |
| 102 | + required_contexts: |
| 103 | + - "publish-image" |
| 104 | + payload: |
| 105 | + application: argocd-demo-dev |
| 106 | + - name: prod |
| 107 | + auto_merge: true |
| 108 | + required_contexts: |
| 109 | + - "publish-image" |
| 110 | + production_environment: true |
| 111 | + payload: |
| 112 | + application: argocd-demo-prod |
| 113 | +``` |
| 114 | +
|
| 115 | +</details> |
| 116 | +
|
| 117 | +<details> |
| 118 | +<summary>GitHub Action Pipeline</summary> |
| 119 | +
|
| 120 | +```yaml |
| 121 | +name: deploy |
| 122 | + |
| 123 | +on: |
| 124 | + deployment |
| 125 | + |
| 126 | +jobs: |
| 127 | + deploy: |
| 128 | + runs-on: ubuntu-latest |
| 129 | + steps: |
| 130 | + - |
| 131 | + uses: chrnorm/deployment-status@releases/v2 |
| 132 | + with: |
| 133 | + deployment-id: ${{ github.event.deployment.id }} |
| 134 | + description: Trigger the pipeline |
| 135 | + state: "queued" |
| 136 | + token: "${{ github.token }}" |
| 137 | + - |
| 138 | + uses: chrnorm/deployment-status@releases/v2 |
| 139 | + with: |
| 140 | + deployment-id: ${{ github.event.deployment.id }} |
| 141 | + description: Start to deploy to the Kubernetes |
| 142 | + log-url: https://gitploy.jp.ngrok.io/applications/${{ github.event.deployment.payload.application }} |
| 143 | + state: "in_progress" |
| 144 | + token: "${{ github.token }}" |
| 145 | + - |
| 146 | + name: Log in |
| 147 | + uses: clowdhaus/argo-cd-action/@main |
| 148 | + with: |
| 149 | + version: 2.3.3 |
| 150 | + command: login gitploy.jp.ngrok.io |
| 151 | + options: > |
| 152 | + --username |
| 153 | + admin |
| 154 | + --password |
| 155 | + ${{ secrets.ARGOCD_PASSWORD }} |
| 156 | + - |
| 157 | + name: Set image tag |
| 158 | + uses: clowdhaus/argo-cd-action/@main |
| 159 | + with: |
| 160 | + version: 2.3.3 |
| 161 | + command: app set ${{ github.event.deployment.payload.application }} |
| 162 | + options: > |
| 163 | + --revision ${{ github.sha }} |
| 164 | + --kustomize-image gitployio/argocd-demo=gitployio/argocd-demo:sha-${{ github.sha }} |
| 165 | + - |
| 166 | + name: Sync |
| 167 | + uses: clowdhaus/argo-cd-action/@main |
| 168 | + with: |
| 169 | + version: 2.3.3 |
| 170 | + command: app sync ${{ github.event.deployment.payload.application }} |
| 171 | + options: > |
| 172 | + --timeout 300 |
| 173 | + - |
| 174 | + name: Wait |
| 175 | + uses: clowdhaus/argo-cd-action/@main |
| 176 | + with: |
| 177 | + version: 2.3.3 |
| 178 | + command: app wait ${{ github.event.deployment.payload.application }} |
| 179 | + options: > |
| 180 | + --health |
| 181 | + --timeout 600 |
| 182 | + - |
| 183 | + if: success() |
| 184 | + uses: chrnorm/deployment-status@releases/v2 |
| 185 | + with: |
| 186 | + deployment-id: ${{ github.event.deployment.id }} |
| 187 | + description: Finish to deploy successfully. |
| 188 | + log-url: https://gitploy.jp.ngrok.io/applications/${{ github.event.deployment.payload.application }} |
| 189 | + state: "success" |
| 190 | + token: "${{ github.token }}" |
| 191 | + - |
| 192 | + if: failure() |
| 193 | + uses: chrnorm/deployment-status@releases/v2 |
| 194 | + with: |
| 195 | + deployment-id: ${{ github.event.deployment.id }} |
| 196 | + description: Failed to deploy. |
| 197 | + log-url: https://gitploy.jp.ngrok.io/applications/${{ github.event.deployment.payload.application }} |
| 198 | + state: "failure" |
| 199 | + token: "${{ github.token }}" |
| 200 | +``` |
| 201 | +
|
| 202 | +</details> |
| 203 | +
|
| 204 | +Now, when we deploy from Gitploy, we can see that the Argo CD pins the Application to the manifests defined at the specified commit. More details for the demo can be found in this [repository](https://github.com/gitploy-io). :) |
| 205 | +
|
| 206 | + |
0 commit comments