Argo CD Pull Request Generatorについて

## はじめに

私は普段SREとしてAWSやEKS(Kubernetes)などのクラウドインフラの運用に従事しています。本記事では、Argo CD Pull Request Generatorについて紹介します。

## そもそも、Argo CD Generaterとは

公式では以下のように紹介されています。

>Generators are responsible for generating parameters, which are then rendered into the template: fields of the ApplicationSet resource. See the Introduction for an example of how generators work with templates, to create Argo CD Applications.

> Generators are primarily based on the data source that they use to generate the template parameters. For example: the List generator provides a set of parameters from a literal list, the Cluster generator uses the Argo CD cluster list as a source, the Git generator uses files/directories from a Git repository, and so.

ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators/

めちゃくちゃ簡単にまとめると、GeneratorはApplicationSetというカスタムリソースを扱います。Generatorが生成したパラメータをApplicationSetのtemplateフィールドに埋め込み、任意のKubernetesリソースを作成できるものです。

＊ ここでいうGeneratorはKubernetes Operatorの認識です。

様々なGeneraterが提供されており、自分で好きなGeneraterを作れるPlugin Generaterもあります。

- List generater
- Git generater
- Matrix generater
- Pull Request generater
- Plugin Generator

## Argo CD Pull Request Generaterとは

Generatorの中でも、今回紹介するのはArgo CD Pull Request Generatorです。Argo CD Pull Request Generatorとは、GitHubのOpenなPull Requestを検知して、それを元に任意のKubernetesリソースをArgo CDアプリケーションとして作成できるGeneratorです。簡単にいうとArgo CDのPull Request版みたいな感じです。

## ApplicationSetリソースの解説

ApplicationSetリソースのマニフェストについて解説します。ソースコード上にコメントしています。

```yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapps
spec:
  generators:
  - pullRequest:
      gitlab:
        project: myproject
        api: https://git.example.com/
        # Pull Requestを取得できるようにtokenRefでGitHub Tokenを指定します。
        tokenRef:
          secretName: gitlab-token
          key: token
        # labelsで検知するPull Requestを絞り込むことができます
        labels:
        - preview
        pullRequestState: opened
      # requeueAfterSecondsでReconcileの間隔を指定します
      requeueAfterSeconds: 60
  template:
    metadata:
        # {{branch}}や{{number}}でブランチ名やPR番号を埋め込めます。
      name: 'myapp-{{branch}}-{{number}}'
    spec:
      source:
        # gitのリポジトリURLを指定します。
        repoURL: 'https://github.com/myorg/myrepo.git'
        targetRevision: '{{head_sha}}'
        path: kubernetes/
        # kustomizeやHelmが使えます。
        kustomize:
          nameSuffix: {{branch}}
          commonLabels:
            app.kubernetes.io/instance: {{branch}}-{{number}}
          images:
          - ghcr.io/myorg/myrepo:{{head_sha}}
      project: "my-project"
      destination:
        server: https://kubernetes.default.svc
        namespace: default
```

## つらいところ

Argo CD Pull Request Generatorは良い部分だけではありません。自分が現在運用している中で2つのデメリットがあると感じています。

1. Docker ImageのBuildを待ってくれない
2. DraftのPull Requestも検知してしまう

1番についてです。GitHubのCommit IDでDokcer Imageを運用しているケースは多いと思います。そういう場合にPull Request Generatorはポーリングのタイミングで即座に`{{head_sha}}`をレンダリングするため、Docker ImageがPullする元のRepositoryに存在しなくても、Argo CD Applicationとして作成されるため、Podがダウンし続けるという現象が起きてしまいます。

2番についてです。開発において、一旦放置したいPull RequestをDraftにすることがあるかと思います。その場合、Pull Request　Generatorのfilter機能としてDraft Pull RequestをIgnoreする機能がないのでDraftのまま放置しておくと環境が作られたままになり、コストがかかります。

## 終わりに
Argo ProjectはDeveloperのusecaseを考えて、様々なGeneraterを開発しているんだなと感じました。plugin generaterという、自作argocd generaterが作れるものも用意されているみたいで機会があれば使ってみたいなと思います。https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Plugin/