Argo Workflowsについて
Argo Workflowsは、Kubernetes上で動作するオープンソースのワークフロー管理ツールです。
https://argoproj.github.io/workflows/
複数のタスクを定義して実行するワークフローを管理・自動化可能であり、複雑なCI/CDパイプラインを簡単に構築することができます。
REST APIの機能も持っており、ワークフローの実行や管理を外部からHTTP経由で実行することも可能です。
ただし、そのためにはサーバーの認証方法でTokenによる認証を有効化し、専用のTokenを生成して管理するなどの対応が必要となります。
既存のCI/CDなどでGitHub ActionsからAWS環境へのアクセスが既に確立されている場合は、awscliやkubectlなどのコマンドを使用した方が新しい侵入経路を作らないため安全です。
この記事では、GitHub Actionsからコマンド経由で、EKS上で動作するArgo Workflowを実行する方法について説明します。
前提条件
以下は事前に用意してあるものとします。
- Argo Workflowsが動作するEKS Cluster
- GitHub ActionsからEKS Clusterにアクセスするための認証設定
- GitHub Actions と AWS環境間のアクセスには GitHub ActionsとAWSの連携におけるOIDC認証の活用 などを参考
- aws-authや access entryによるIAMロールとKubernetesの権限周りのマッピングも必要
また、実行した環境は以下のとおりです。
- EKS Cluster: v1.29.10-eks-7f9249a
- Argo Workflows: v3.5.1
単純にGitHub ActionsからArgo Workflowsのワークフローを実行するケース
以下のようなGitHub Actionsのワークフローを定義することで、argocliをインストールでき、 argo submit コマンドを実行できるようになります。
name: Sample Workflow
on:
workflow_dispatch:
# OIDC認証を利用するためid-token: writeを設定する
permissions:
actions: write
contents: read
id-token: write
pull-requests: write
env:
ROLE_ARN: arn:aws:iam::123456789012:role/role-name
CLUSTER_NAME: cluster-name
REGION: ap-northeast-1
KUBERNETES_VERSION: v1.29.0
ARGOCLI_VERSION: v3.5.1
jobs:
sample-workflow:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.ROLE_ARN }}
aws-region: ${{ env.REGION }}
- name: Install kubectl command
uses: azure/setup-kubectl@v4
with:
version: ${{ env.KUBERNETES_VERSION }}
- name: Install Argo CLI
run: |
curl -sLO https://github.com/argoproj/argo-workflows/releases/download/${{ env.ARGOCLI_VERSION }}/argo-linux-amd64.gz
gunzip argo-linux-amd64.gz
chmod +x argo-linux-amd64
sudo mv argo-linux-amd64 /usr/local/bin/argo
- name: Submit Argo Workflow
id: submit-workflow
run: |
aws eks --region ${{ env.REGION }} update-kubeconfig --name ${{ env.CLUSTER_NAME }}
# 同じリポジトリで管理しているargo_sample.yamlを渡して実行する
# --wait オプションを渡すことで実行完了まで待機する
argo submit argo_sample.yaml --wait -o json -n <NAMESPACE>
argo submit
コマンドに、argo workflows上で動作させるワークフローの定義ファイルを渡すことで実行が行われます。
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: example-workflow
spec:
entrypoint: whalesay
serviceAccountName: executor
templates:
- name: whalesay
container:
image: docker/whalesay:latest
command: [echo]
args: ["hello world"]
WorkflowTemplateを設定して呼び出すケース
上記の方法で、指定したWorkflowを実行できます。
ただし、GitHub Actionsと同じリポジトリでWorkflowのファイルを管理する必要があるため、ArgoWorkflowsのリソースを管理しているリポジトリと、GitHub Actionsを実行したいリポジトリが異なる場合などに、リソースの定義が散らばってしまいます。
ArgoWorkflowsのリソースをまとめておきたい場合にはargo subimit
コマンドの --from
オプションが活用できます。
--from
オプションを使用することでArgoWorkflowに登録済みのリソースを呼び出すことができます。
例えば次のようなWorkflowTemplateを登録しておいて、こちらを基にしてWorkflowを起動するなどが可能です。
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: workflowtemplate-sample
spec:
serviceAccountName: <SERVICE_ACCOUNT_NAME>
entrypoint: whalesay
ttlStrategy:
secondsAfterCompletion: 3600 # 1 hour
templates:
- name: whalesay
container:
image: docker/whalesay:latest
command:
- sh
- -c
- |
echo "hello world"
- name: Submit Argo Workflow
id: submit-workflow
run: |
aws eks --region ${{ env.REGION }} update-kubeconfig --name ${{ env.CLUSTER_NAME }}
# workflowtemplate を呼び出す
argo submit --from workflowtemplate/workflowtemplate-sample --wait -o json -n <NAMESPACE>
ArgoWorkflows側での実行結果を呼び出し側で取得するケース
上記のように argo submit
の実行によってworkflowを起動することができますが、その結果をGitHub Actions側の後続処理に渡したい場合などがあります。そのようなケースではパラメータが活用できます。
以下はGitHub Actions側から入力用のパラメータを渡し、ArgoWorkflows側での実行結果を出力用のパラメータとして出力する場合の例となります。
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: workflowtemplate-sample
spec:
serviceAccountName: <SERVICE_ACCOUNT_NAME>
entrypoint: whalesay
arguments:
parameters:
- name: message
value: "" # set the value by argo submit --parameter
ttlStrategy:
secondsAfterCompletion: 3600 # 1 hour
templates:
- name: whalesay
inputs:
parameters:
- name: message
outputs:
parameters:
- name: output-message
valueFrom:
path: /tmp/hello_world.txt
container:
image: docker/whalesay:latest
command:
- sh
- -c
- |
echo -n {{inputs.parameters.message}} > /tmp/hello_world.txt
GitHub Actions側では実行結果がそのまま返ってくるものではないので、起動されたワークフロー名を基にして結果を取得しにいく必要があります。
# --parameter でworkflowに入力値として渡すパラメータを設定し、実行時に出力される情報をworkflow.jsonに保存する
argo submit --from workflowtemplate/workflowtemplate-sample --wait -o json -n <Namespace> --parameter message="Hello, world!" > workflow.json
# workflow.jsonから実行されたworkflowの名前を取得
WORKFLOW_NAME=$(< workflow.json jq -r '.metadata.name')
echo "workflow name : $WORKFLOW_NAME"
# 実行完了後の情報をargo_get_result.jsonに保存
argo get -n <NAMESPACE> "$WORKFLOW_NAME" -o json > argo_get_result.json
# argo_get_result.json から実行後のステータスやoutputsパラメータに設定した情報を取得する
ARGO_WORKFLOW_RESULT=$(< argo_get_result.json jq -r '.status.phase')
echo "workflow result : $ARGO_WORKFLOW_RESULT"
RESULT_MESSAGE=$(< argo_get_result.json jq -r '.status.nodes' |jq -r ".\"$WORKFLOW_NAME\"" | jq -r '.outputs.parameters[] | select(.name == "output-message").value')
echo "result : $RESULT_MESSAGE"
このような方法でArgo Workflows側での結果をGitHub Actions側に持ってくることができます。
おわりに
以上、GitHub ActionsからEKS上で動作するArgo Workflowsを実行する際の対応例を複数パターンで紹介しました。
同じような対応が必要になった際には、参考にしてみてください。