dockerkubernetesamazon-ecrargo-workflowsargo

why Argoworkflows multi-app-docker-build image with kaniko fails


new to argworkflows ** I am trying to create a workflow that takes the name of the application that we are going to build the docker image for and push it to an ECR .**

this is my workflow.yaml:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: build-image
  namespace: argo-workflows
spec:
  serviceAccountName: argo-workflow
  entrypoint: build-and-deploy-env3
  arguments:
    parameters:
      - name: env_name
        value: test
      - name: aws_region
        value: eu-west-1
      - name: expiration_date
        value: "2024-12-31T23:59:59Z"
      - name: values_path
        value: ./demo-app/helm/values.yaml
      - name: configurations
        value: '[{"keyPath": "global.app.main.name", "value": "updated-app"}, {"keyPath": "global.service.backend.port", "value": 8080}]'
      - name: application_list
        value: '[{"name": "backend", "repo_url": "org/project-demo-app.git", "branch": "demo-app", "ecr_repo": "demo-app/backend", "path_inside_repo": "backend"}, {"name": "frontend", "repo_url": "org/project-demo-app.git", "branch": "demo-app", "ecr_repo": "demo-app/frontend", "path_inside_repo": "frontend"}]'

  templates:
    - name: build-and-deploy-env3
      dag:
        tasks:
          - name: build-push-app
            template: build-push-template
            arguments:
              parameters:
                - name: app
                  value: "{{item}}"
            withParam: "{{workflow.parameters.application_list}}"

    - name: build-push-template
      inputs:
        parameters:
          - name: app
      dag:
        tasks:
          - name: clone-and-check
            template: clone-and-check-template
            arguments:
              parameters:
                - name: app
                  value: "{{inputs.parameters.app}}"

          - name: build-and-push
            template: kaniko-build-template
            arguments:
              parameters:
                - name: name
                  value: "{{tasks.clone-and-check.outputs.parameters.name}}"
                - name: image_tag
                  value: "{{tasks.clone-and-check.outputs.parameters.image_tag}}"
                - name: ecr_url
                  value: "{{tasks.clone-and-check.outputs.parameters.ecr_url}}"
                - name: ecr_repo
                  value: "{{tasks.clone-and-check.outputs.parameters.ecr_repo}}"
                - name: path_inside_repo
                  value: "{{tasks.clone-and-check.outputs.parameters.path_inside_repo}}"
            when: "{{tasks.clone-and-check.outputs.parameters.build_needed}} == true"
            dependencies: [clone-and-check]
          - name: debug-list-files
            template: debug-list-files
            arguments:
              parameters:
                - name: name
                  value: "{{tasks.clone-and-check.outputs.parameters.name}}"
                - name: path_inside_repo
                  value: "{{tasks.clone-and-check.outputs.parameters.path_inside_repo}}"
            dependencies: [clone-and-check]
    - name: clone-and-check-template
      inputs:
        parameters:
          - name: app
      outputs:
        parameters:
          - name: name
            valueFrom:
              path: /tmp/name
          - name: image_tag
            valueFrom:
              path: /tmp/image_tag
          - name: ecr_url
            valueFrom:
              path: /tmp/ecr_url
          - name: ecr_repo
            valueFrom:
              path: /tmp/ecr_repo
          - name: path_inside_repo
            valueFrom:
              path: /tmp/path_inside_repo
          - name: build_needed
            valueFrom:
              path: /tmp/build_needed
      container:
        image: bitnami/git:latest
        command: [bash, -c]
        args:
          - |
            set -e
            apt-get update && apt-get install -y jq awscli

            APP=$(echo '{{inputs.parameters.app}}' | jq -r '.name')
            REPO_URL=$(echo '{{inputs.parameters.app}}' | jq -r '.repo_url')
            BRANCH=$(echo '{{inputs.parameters.app}}' | jq -r '.branch')
            ECR_REPO=$(echo '{{inputs.parameters.app}}' | jq -r '.ecr_repo')
            PATH_INSIDE_REPO=$(echo '{{inputs.parameters.app}}' | jq -r '.path_inside_repo')

            git clone --branch $BRANCH https://x-access-token:$ALL_REPO_ORG_ACCESS@github.com/$REPO_URL /workspace/application-$APP
            cd /workspace/application-$APP/$PATH_INSIDE_REPO
            ls -l
            if [[ ! -f "Dockerfile" ]]; then
              echo "Dockerfile not found in $PATH_INSIDE_REPO"
              exit 1
            fi

            COMMIT_HASH=$(git rev-parse --short HEAD)
            IMAGE_TAG="${APP}-${BRANCH}-${COMMIT_HASH}-{{workflow.parameters.env_name}}"

            ECR_URL="$AWS_ACCOUNT_ID.dkr.ecr.{{workflow.parameters.aws_region}}.amazonaws.com"
            EXISTS=$(aws ecr describe-images --repository-name $ECR_REPO --image-ids imageTag=$IMAGE_TAG 2>/dev/null || echo "not-found")

            if [[ "$EXISTS" != "not-found" ]]; then
              echo "false" > /tmp/build_needed
            else
              echo "true" > /tmp/build_needed
            fi

            echo "$APP" > /tmp/name
            cat /tmp/name
            echo "$IMAGE_TAG" > /tmp/image_tag
            echo "$ECR_URL" > /tmp/ecr_url
            echo "$ECR_REPO" > /tmp/ecr_repo
            echo "$PATH_INSIDE_REPO" > /tmp/path_inside_repo
            cat /tmp/path_inside_repo
            
        env:
          - name: ALL_REPO_ORG_ACCESS
            valueFrom:
              secretKeyRef:
                name: github-creds
                key: ALL_REPO_ORG_ACCESS
          - name: AWS_ACCOUNT_ID
            valueFrom:
              secretKeyRef:
                name: registry-creds
                key: AWS_ACCOUNT_ID
          - name: AWS_REGION
            value: "{{workflow.parameters.aws_region}}"
        volumeMounts:
          - name: workspace
            mountPath: /workspace
    - name: debug-list-files
      inputs:
        parameters:
          - name: name
          - name: path_inside_repo
      container:
        image: alpine:latest
        command: [sh, -c]
        args:
          - ls -l /workspace
      volumeMounts:
        - name: workspace
          mountPath: /workspace
    - name: kaniko-build-template
      inputs:
        parameters:
          - name: name
          - name: image_tag
          - name: ecr_url
          - name: ecr_repo
          - name: path_inside_repo
      container:
        image: gcr.io/kaniko-project/executor:latest
        command:
          - /kaniko/executor
        args:
          - --context=dir:///workspace/application-{{inputs.parameters.name}}/{{inputs.parameters.path_inside_repo}}
          - --dockerfile=Dockerfile
          - --destination={{inputs.parameters.ecr_url}}/{{inputs.parameters.ecr_repo}}:{{inputs.parameters.image_tag}}
          - --cache=true
          - --verbosity=debug
        env:
          - name: AWS_REGION
            value: "{{workflow.parameters.aws_region}}"
        volumeMounts:
          - name: workspace
            mountPath: /workspace

  volumes:
    - name: workspace
      emptyDir: {}

I my kaniko step fails with this error : kaniko pod error

although i did the cat in the previous step and i did add the dockerfile to the shared volume i can't understand why it can't find the dockerfile . this is the previous step of logs : git-checkout


Solution

  • As @Thomas Delrue pointed out, the issue was caused by using an emptyDir volume. However, instead of switching to a PersistentVolume (PV), I initially intended to use artifacts .

    Here's my updated Argo Workflow file:

    apiVersion: argoproj.io/v1alpha1
    kind: Workflow
    metadata:
      generateName: build-image
      namespace: argo-workflows
    spec:
      serviceAccountName: argo-workflow
      entrypoint: build-and-deploy-env
      arguments:
        parameters:
          - name: env_name
            value: test
          - name: aws_region
            value: eu-west-1
          - name: expiration_date
            value: "2024-12-31T23:59:59Z"
          - name: values_path
            value: ./demo-app/helm/values.yaml
          - name: configurations
          - name: configurations
            value: '[{"keyPath": "global.app.main.name", "value": "updated-app"}, {"keyPath": "global.service.backend.port", "value": 8080}]'
          - name: application_list
            value: '[{"name": "backend", "repo_url": "org/project-demo-app.git", "branch": "demo-app", "ecr_repo": "demo-app/backend", "path_inside_repo": "backend"}, {"name": "frontend", "repo_url": "org/project-demo-app.git", "branch": "demo-app", "ecr_repo": "demo-app/frontend", "path_inside_repo": "frontend"}]'
    
      templates:
        - name: build-and-deploy-env
          dag:
            tasks:
              - name: build-push-app
                template: build-push-template
                arguments:
                  parameters:
                    - name: app
                      value: "{{item}}"
                withParam: "{{workflow.parameters.application_list}}"
    
        - name: build-push-template
          inputs:
            parameters:
              - name: app
          dag:
            tasks:
              - name: clone-and-check
                template: clone-and-check-template
                arguments:
                  parameters:
                    - name: app
                      value: "{{inputs.parameters.app}}"
    
              - name: build-and-push
                template: kaniko-build-template
                arguments:
                  parameters:
                    - name: name
                      value: "{{tasks.clone-and-check.outputs.parameters.name}}"
                    - name: image_tag
                      value: "{{tasks.clone-and-check.outputs.parameters.image_tag}}"
                    - name: ecr_url
                      value: "{{tasks.clone-and-check.outputs.parameters.ecr_url}}"
                    - name: ecr_repo
                      value: "{{tasks.clone-and-check.outputs.parameters.ecr_repo}}"
                  artifacts:
                    - name: source-code
                      from: "{{tasks.clone-and-check.outputs.artifacts.source-code}}"
                when: "{{tasks.clone-and-check.outputs.parameters.build_needed}} == true"
                dependencies: [clone-and-check]
    
              - name: debug-list-files
                template: debug-list-files
                arguments:
                  parameters:
                    - name: name
                      value: "{{tasks.clone-and-check.outputs.parameters.name}}"
                  artifacts:
                    - name: source-code
                      from: "{{tasks.clone-and-check.outputs.artifacts.source-code}}"
                dependencies: [clone-and-check]
    
        - name: clone-and-check-template
          inputs:
            parameters:
              - name: app
          outputs:
            parameters:
              - name: name
                valueFrom:
                  path: /tmp/name
              - name: image_tag
                valueFrom:
                  path: /tmp/image_tag
              - name: ecr_url
                valueFrom:
                  path: /tmp/ecr_url
              - name: ecr_repo
                valueFrom:
                  path: /tmp/ecr_repo
              - name: path_inside_repo
                valueFrom:
                  path: /tmp/path_inside_repo
              - name: build_needed
                valueFrom:
                  path: /tmp/build_needed
            artifacts:
              - name: source-code
                path: /workspace/source
          container:
            image: bitnami/git:latest
            command: [bash, -c]
            args:
              - |
                set -e
                apt-get update && apt-get install -y jq awscli
    
                APP=$(echo '{{inputs.parameters.app}}' | jq -r '.name')
                REPO_URL=$(echo '{{inputs.parameters.app}}' | jq -r '.repo_url')
                BRANCH=$(echo '{{inputs.parameters.app}}' | jq -r '.branch')
                ECR_REPO=$(echo '{{inputs.parameters.app}}' | jq -r '.ecr_repo')
                PATH_INSIDE_REPO=$(echo '{{inputs.parameters.app}}' | jq -r '.path_inside_repo')
    
                # Clone to the artifact path
                git clone --branch $BRANCH https://x-access-token:$ALL_REPO_ORG_ACCESS@github.com/$REPO_URL /workspace/source
                cd /workspace/source/$PATH_INSIDE_REPO
                
                if [[ ! -f "Dockerfile" ]]; then
                  echo "Dockerfile not found in $PATH_INSIDE_REPO"
                  exit 1
                fi
    
                COMMIT_HASH=$(git rev-parse --short HEAD)
                IMAGE_TAG="${APP}-${BRANCH}-${COMMIT_HASH}-{{workflow.parameters.env_name}}"
    
                ECR_URL="$AWS_ACCOUNT_ID.dkr.ecr.{{workflow.parameters.aws_region}}.amazonaws.com"
                EXISTS=$(aws ecr describe-images --repository-name $ECR_REPO --image-ids imageTag=$IMAGE_TAG 2>/dev/null || echo "not-found")
    
                if [[ "$EXISTS" != "not-found" ]]; then
                  echo "false" > /tmp/build_needed
                else
                  echo "true" > /tmp/build_needed
                fi
    
                echo "$APP" > /tmp/name
                echo "$IMAGE_TAG" > /tmp/image_tag
                echo "$ECR_URL" > /tmp/ecr_url
                echo "$ECR_REPO" > /tmp/ecr_repo
                echo "$PATH_INSIDE_REPO" > /tmp/path_inside_repo
                
            env:
              - name: ALL_REPO_ORG_ACCESS
                valueFrom:
                  secretKeyRef:
                    name: github-creds
                    key: ALL_REPO_ORG_ACCESS
              - name: AWS_ACCOUNT_ID
                valueFrom:
                  secretKeyRef:
                    name: registry-creds
                    key: AWS_ACCOUNT_ID
              - name: AWS_REGION
                value: "{{workflow.parameters.aws_region}}"
    
        - name: debug-list-files
          inputs:
            parameters:
              - name: name
            artifacts:
              - name: source-code
                path: /workspace/source
          container:
            image: alpine:latest
            command: [sh, -c]
            args:
              - |
                echo "=== Listing /workspace/source ==="
                ls -la /workspace/source
                echo "=== Listing application directory ==="
                ls -la /workspace/source/*/
                echo "=== Finding Dockerfiles ==="
                find /workspace/source -name "Dockerfile" -type f
    
        - name: kaniko-build-template
          inputs:
            parameters:
              - name: name
              - name: image_tag
              - name: ecr_url
              - name: ecr_repo
            artifacts:
              - name: source-code
                path: /workspace/source
          container:
            image: gcr.io/kaniko-project/executor:latest
            command:
              - /kaniko/executor
            args:
              - --context=dir:///workspace/source/{{inputs.parameters.name}}
              - --dockerfile=Dockerfile
              - --destination={{inputs.parameters.ecr_url}}/{{inputs.parameters.ecr_repo}}:{{inputs.parameters.image_tag}}
              - --cache=true
              - --verbosity=debug
            env:
              - name: AWS_REGION
                value: "{{workflow.parameters.aws_region}}"
              - name: AWS_ACCESS_KEY_ID
                valueFrom:
                  secretKeyRef:
                    name: registry-creds
                    key: AWS_ACCESS_KEY_ID
              - name: AWS_SECRET_ACCESS_KEY
                valueFrom:
                  secretKeyRef:
                    name: registry-creds
                    key: AWS_SECRET_ACCESS_KEY
              - name: AWS_SESSION_TOKEN
                valueFrom:
                  secretKeyRef:
                    name: registry-creds
                    key: AWS_SESSION_TOKEN
              - name: AWS_SDK_LOAD_CONFIG
                value: "true"