既存のHelmChartをArgoCD管理に移行する

本記事は [QualiArts Advent Calendar 2023](https://qiita.com/advent-calendar/2023/qualiarts "")16日目の記事です。

初めまして、IDOLY PRIDE(以下、アイプラ)でバックエンドチームのリーダーをしている末吉です。

アイプラでは、APIサーバーのコンピューティングにGoogle Kuberentes Engineを利用しており、KubernetesのパッケージマネージャーにHelmを使用しています。

既存のHelmChartをArgoCD管理に移行する機会があったので、ArgoCDの概要に触れつつ、その手順とメリットについて紹介できたらと思います。

# GitOps

ArgoCDについて説明する前に、まずはGitOpsについて簡単に説明します。

GitOpsとは、ソースコードや設定情報をGitで管理し、そのGitのリポジトリをシステムの唯一のソースとして扱うCDの手法です。

大きな特徴としては、設定の変更が全てGit上で行われ、その変更が自動的にインフラに反映されることが挙げられます。


# ArgoCD

上述したGitOpsを実現するツールとして、ArgoCDをアイプラでは使用しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/db6ff407-da08-b991-4db3-5b4498845a3a.png)

https://github.com/argoproj/argo-cd


 - GUIの使いやすさ、豊富さ
     - Deploymentだけでなく、CustomResourceDefinitionの表示までしてくれる
 - 必要最低限の機能による、学習コストの低さ
     - 「デプロイが失敗したらxxをする」等の自由度の高いCDパイプラインを構築したければArgo Workflowsを後から導入も可能


に魅力を感じ、採用に至ってます。


# ArgoCDに移行する手順

さて、本題の移行手順に入っていきます。

下記のようなHelmChartがあるとします。

```
- sample-app
    - .helmignore
    - Chart.yaml
    - templates/
        - namespace.yaml
        - deployment.yaml
    - values.yaml
    - values-dev.yaml
```

```yaml:namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: sample
```

```yaml:deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
  namespace: sample
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.10
        ports:
        - containerPort: 80
```

まずはhelmでデプロイします。

```bash
$ helm install sample-app ./ -f ./values-dev.yaml
```

次に、ArgoCDのApplicationファイル群を用意していきます。

```
- argo-app
    - .helmignore
    - Chart.yaml
    - templates/
        - sample-app.yaml
    - values.yaml
    - values-dev.yaml
```

```yaml:sample-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: sample-app
spec:
  destination:
    namespace: sample
    server: 'https://kubernetes.default.svc'
  source:
    path: sample-app
    repoURL: '{GitのURL}'
    targetRevision: {{ .Values.targetRevision }}
    helm:
      valueFiles:
      {{- with $.Values.valuesFile }}
        {{- toYaml . | nindent 8 }}
      {{- end }}
  project: default
  syncPolicy:
    automated:
      prune: false

```

```yaml:values-dev.yaml
targetRevision: master

valuesFile:
  - values-dev.yaml
```

重要なポイントが下記の2つとなります。

- metadata.nameはHelmのChart名と一致させる
- destination.namespaceはHelmのChartをinstallしたnamespaceと一致させる

どちらの条件も満たしている場合、ArgoCDは既存のリリースとしてみなして、インストールするのではなくHelm経由でデプロイされているチャートと同期し、Argo管理下に置きます。

最後に、helm installを行えば無事にArgo管理下に置かれます。

```
$ helm install argo-app ./ -f ./values-dev.yaml
```

# 実際に移行してみて感じたメリット

### 1. オペレーションミスが減ることによるサービスの信頼性の向上

GitOpsでは、リポジトリにpushすれば元々設定しておいた環境(向き先)に自動反映されるので、手動でのコマンドミスが殆どなくなります。

`` kubectl apply`` や``helm upgrade``を誤って本番環境に向けて実行してしまった、、という事がなくなるのは大きいですね。

また、設定の変更はGitHubで行われるので

- PullRequestで他の人がレビューする
- CIツールを走らせて、マニフェストファイルの静的解析を行う
 
等を行い、事故や設定ミスを反映前に未然に防ぐこともできます。


### 2. インフラ作業コストの低下

Gitであればアプリケーションエンジニアでも慣れ親しんでいるので、デプロイ作業も非常に手軽に出来ます。

また、万が一間違った設定を反映させてしまった場合でも、``git revert`` をしてpushすれば容易にロールバックも可能です。


# 最後に

本記事では既存のHelmChartをArgoCD管理に移行する手順について説明しました。

本記事が皆さまの運用に少しでもお役に立てば幸いです。