Skip to content

Creación de pipeline de Produccion

Laboratorio: Creación de pipeline de Produccion

Descripción

La presente guía enseña al estudiante el proceso de creación de pipelines como código para Gitlab CI.

Objetivos

  • Modificar los flujos para acomodar el paso a producción.
  • Crear un pipeline que corra a través de Gitlab CI.

Antes de comenzar

  • Contar con el acceso al ambiente del laboratorio

Inicio de laboratorio

  1. Acceda a la carpeta angular-demo

  2. Verifique en que rama se encuentra y cambie a dev

    git branch
    git checkout dev
    

  3. Edite el archivo ci-templates/.dev.yaml cambiando/agregando las siguientes variables (se agrega -dev al final del valor)

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    variables:
      KUBECONFIG: $KUBECONFIG_DEV
      REGISTRY_URL: $REGISTRY_URL_DEV
      REGISTRY_USER: $REGISTRY_USER_DEV
      TOKEN: $TOKEN_DEV
      SONAR_ARGS: "-Dsonar.projectName=${PROJECT_NAME} -Dsonar.projectKey=some.org:${PROJECT_NAME} -Dsonar.host.url=$SONAR_URL -Dsonar.sources=. -Dsonar.login=$SONAR_TOKEN -Dsonar.coverage.exclusions=node_modules/*"
      PROJECT_NAME: "angular-demo-dev"
      SONAR_URL: "http://sonarqube.35-197-67-208.nip.io/"
      REGISTRY_PROJECT: "apis"
      IMAGE_NAME: "angular-demo"
      DEPLOYMENT_NAME: "angular-demo-dev"
      NAMESPACE: "userx"
      SERVICE_PORT: "80"
      INGRESS_HOST: "angular-demo-dev.x-x-x-x.nip.io"
      PROMOTE_SHA: "yes"
    

  4. Edite el archivo ci-templates/.dev.yaml eliminando de todos los Jobs la siguiente regla

    rules:
      - if: $CI_COMMIT_BRANCH =~ /dev*/
    

  5. Edite el archivo ci-templates/.qa.yaml cambiando/agregando las siguientes variables (se agrega -qa al final del valor)

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    variables:
      KUBECONFIG: $KUBECONFIG_QA
      REGISTRY_URL: $REGISTRY_URL_QA
      REGISTRY_USER: $REGISTRY_USER_QA
      TOKEN: $TOKEN_QA
      PROJECT_NAME: "angular-demo-qa"
      REGISTRY_PROJECT: "apis"
      IMAGE_NAME: "angular-demo"
      DEPLOYMENT_NAME: "angular-demo-qa"
      NAMESPACE: "userx"
      SERVICE_PORT: "80"
      INGRESS_HOST: "angular-demo-qa.x-x-x-x.nip.io"
      SRC_TLS_VERIFY: "false"
      DEST_TLS_VERIFY: "false"
    

  6. Edite el archivo ci-templates/.qa.yaml eliminando de todos los Jobs la siguiente regla

    rules:
      - if: $CI_COMMIT_BRANCH =~ /qa*/
    

  7. Edite el archivo .gitlab-ci.yml dividiendo el include: local a uno por cada archivo de pipeline (dev y qa)

    include:
      - local: 'ci-templates/.dev.yaml'
      - local: 'ci-templates/.qa.yaml'
    

  8. Agregue a los include una rule que verifique la rama en la que se esta trabajando

    include:
      - local: 'ci-templates/.dev.yaml'
        rules:
          - if: $CI_COMMIT_BRANCH =~ /^dev*/
      - local: 'ci-templates/.qa.yaml'
        rules:
          - if: $CI_COMMIT_BRANCH =~ /^qa*/
    

  9. Elimine los stages del archivo .gitlab-ci.yml

  10. Agregue los stages correspondientes a cada archivo de pipeline en ci-templates

    === ".dev.yaml"

    stages:
      - package
      - analyze
      - build
      - deploy
    
    === ".qa.yaml"
    stages:
      - analyze
      - promote
      - deploy
      - test
    

  11. Configure cache para npm en ci-templates/.dev.yaml en el paso de package

    1
    2
    3
    4
    5
    cache:
      key: npm
      policy: pull-push
      paths:
        - .npm/
    

  12. Configure el script del Job package para utilizar cache

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package-dev:
      stage: package
      image: node:14.15.5
      artifacts:
        expire_in: 2 hrs
        paths:
          - dist
      tags:
        - dev
      script:
        - |
          echo "[INFO] Configurando cache"
          npm ci --cache .npm --prefer-offline
    
          echo "[INFO] Empaquetando en archivos web"
          npm run build
    
          echo "[INFO] Package Exitoso!"
          ls -l dist
    

  13. Edite el archivo ci-templates/.qa.yaml el Job promote-image-qa para que guarde el commit sha

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    promote-image-qa:
      stage: promote
      tags:
        - qa
      artifacts:
        paths:
          - .sha-image
        expire_in: 1 week
      image:
        name: quay.io/skopeo/stable:v1.20.0
        entrypoint: ["/bin/bash", "-c"]
      script:
        - |
          if [ $PROMOTE_SHA == 'yes' ]; then
            echo $CI_COMMIT_SHORT_SHA > .sha-image
          fi
           curl -o .sha-image --header "PRIVATE-TOKEN: ${PROJECT_TOKEN}" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/artifacts/dev/raw/.sha-image?job=build-image-dev"
    
          LAST_COMMIT=$(cat .sha-image)
          skopeo login -u "$REGISTRY_USER" --password "$TOKEN" $REGISTRY_URL --tls-verify=$DEST_TLS_VERIFY
          LAST_IMAGE=$(echo $REGISTRY_URL/$REGISTRY_PROJECT/$IMAGE_NAME):${LAST_COMMIT}
          echo $REGISTRY_URL/$REGISTRY_PROJECT/$IMAGE_NAME:${LAST_COMMIT}
          skopeo copy docker://$LAST_IMAGE docker://$REGISTRY_URL/$REGISTRY_PROJECT/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA  --src-tls-verify=${SRC_TLS_VERIFY} --dest-tls-verify=${DEST_TLS_VERIFY}
    

  14. Agregue al archivo ci-templates/.qa.yaml la variable PROMOTE_SHA

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    variables:
      KUBECONFIG: $KUBECONFIG_QA
      REGISTRY_URL: $REGISTRY_URL_QA
      REGISTRY_USER: $REGISTRY_USER_QA
      TOKEN: $TOKEN_QA
      PROJECT_NAME: "angular-demo-qa"
      REGISTRY_PROJECT: "apis"
      IMAGE_NAME: "angular-demo"
      DEPLOYMENT_NAME: "angular-demo-qa"
      NAMESPACE: "userx"
      SERVICE_PORT: "80"
      INGRESS_HOST: "angular-demo-qa.x-x-x-x.nip.io"
      SRC_TLS_VERIFY: "false"
      DEST_TLS_VERIFY: "false"
      JMETER_FILE: "jmeter.xml"
      PROMOTE_SHA: "yes"
    

  15. Ingrese al repositorio en Gitlab > Settings > CI/CD > Variables

  16. Elimine las variables REGISTRY_URL, REGISTRY_USER y TOKEN

  17. Cree las siguientes variables en Gitlab

    Nombre Tipo Valor Protected Mask
    REGISTRY_URL_DEV Variable harbor.x-x-x-x.nip.io
    REGISTRY_URL_QA Variable harbor.x-x-x-x.nip.io
    REGISTRY_URL_PROD Variable harbor.x-x-x-x.nip.io
    REGISTRY_USER_DEV Variable pull-image
    REGISTRY_USER_QA Variable pull-image
    REGISTRY_USER_PROD Variable pull-image
    TOKEN_DEV Variable Pull1234
    TOKEN_QA Variable Pull1234
    TOKEN_PROD Variable Pull1234
    KUBECONFIG_DEV Variable kubeconfig en base64 del cluster
    KUBECONFIG_QA Variable kubeconfig en base64 del cluster
    KUBECONFIG_PROD Variable kubeconfig en base64 del cluster
  18. Edite los Jobs apply de ambos .dev.yaml y .qa.yaml de la siguiente manera

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
      script:
        - |
    
          echo "[INFO] Reemplazando variables en archivo template"
          envsubst < manifests/k8s-template.yaml > k8s-resources.yaml
    
          echo "[INFO] Recursos creados con valores substituidos"
          cat k8s-resources.yaml
    
          echo "[INFO] Desplegando aplicación"
          kubectl apply -f k8s-resources.yaml
    

  19. Guarde y suba los cambios

    git add .
    git commit -m "Upd ci"
    git push
    

  20. Revise en el portal de gitlab el pipeline de la rama dev y espere que termine

  21. Haga un merge request de la rama dev a la rama qa y realice el procedimiento requerido Nota: Recuerde revisar los repositorios en el merge request, que sean los de su usuario

  22. Revise la ejecución del pipeline de la rama qa creado después de hacer merge

  23. Cambie a la rama qa en el repositorio local y traiga los cambios

    git checkout qa
    git pull
    

  24. Cree una rama nueva llamada merge/qa-to-main

    git checkout -b merge/qa-to-main
    

  25. Cree el archivo ci-templates/.prod.yaml con el siguiente contenido

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    variables:
      KUBECONFIG: $KUBECONFIG_PROD
      REGISTRY_URL: $REGISTRY_URL_PROD
      REGISTRY_USER: $REGISTRY_USER_PROD
      TOKEN: $TOKEN_PROD
      PROJECT_NAME: "angular-demo-prod"
      REGISTRY_PROJECT: "api-test"
      IMAGE_NAME: "angular-demo"
      DEPLOYMENT_NAME: "angular-demo-prod"
      NAMESPACE: "userx"
      SERVICE_PORT: "80"
      INGRESS_HOST: "angular-demo-prod.x-x-x-x.nip.io"
      SRC_TLS_VERIFY: "false"
      DEST_TLS_VERIFY: "false"
    
    stages:
      - analyze
      - promote
      - deploy
    
    policy-test-prod:
      stage: analyze
      image:
        name: openpolicyagent/conftest:v0.32.0
        entrypoint:
          - ""
      tags:
        - prod
      script:
        - conftest test -p manifests/policy.rego manifests/k8s-template.yaml --output=junit > policy_results.xml
      artifacts:
        reports:
          junit: policy_results.xml
    
    promote-image-prod:
      stage: promote
      tags:
        - prod
      image:
        name: quay.io/skopeo/stable:v1.20.0
        entrypoint: ["/bin/bash", "-c"]
      script:
        - |
          if [ $PROMOTE_SHA == 'yes' ]; then
            echo $CI_COMMIT_SHORT_SHA > .sha-image
          fi
          curl -o .sha-image --header "PRIVATE-TOKEN: ${PROJECT_TOKEN}" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/artifacts/qa/raw/.sha-image?job=promote-image-qa"
    
          LAST_COMMIT=$(cat .sha-image)
          skopeo login -u "$REGISTRY_USER" --password "$TOKEN" $REGISTRY_URL --tls-verify=$DEST_TLS_VERIFY
          LAST_IMAGE=$(echo $REGISTRY_URL/$REGISTRY_PROJECT/$IMAGE_NAME):${LAST_COMMIT}
          echo $REGISTRY_URL/$REGISTRY_PROJECT/$IMAGE_NAME:${LAST_COMMIT}
          skopeo copy docker://$LAST_IMAGE docker://$REGISTRY_URL/$REGISTRY_PROJECT/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA  --src-tls-verify=${SRC_TLS_VERIFY} --dest-tls-verify=${DEST_TLS_VERIFY}
    
    
    apply-prod:
      stage: deploy
      image: quay.io/itmlabs/kubectl-tools:v0.0.1
      tags:
        - prod
      script:
        - |
    
          echo "[INFO] Reemplazando variables en archivo template"
          envsubst < manifests/k8s-template.yaml > k8s-resources.yaml
    
          echo "[INFO] Recursos creados con valores substituidos"
          cat k8s-resources.yaml
    
          echo "[INFO] Desplegando aplicación"
          kubectl apply -f k8s-resources.yaml
    

  26. Edite el archivo .gitlab-ci.yml agregando el include correspondiente

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    include:
      - local: 'ci-templates/.dev.yaml'
        rules:
          - if: $CI_COMMIT_BRANCH =~ /^dev*/
      - local: 'ci-templates/.qa.yaml'
        rules:
          - if: $CI_COMMIT_BRANCH =~ /^qa*/
      - local: 'ci-templates/.prod.yaml'
        rules:
          - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    

  27. Guarde y suba los cambios

    git add .
    git commit -m "Add prod ci"
    git push -u origin merge/qa-to-main -o ci.skip
    

  28. Cree un merge request de la rama merge/qa-to-main hacia la rama main

  29. Apruebe el merge

  30. Aplicar Protected y Guardar

  31. Vuelva al apartado de Pipelines

  32. Espere que termine el pipeline

  33. Verifique el nuevo despliegue

    kubectl get all,svc,ingress -n userx