CI/CD Advance

gitlab duo chat

질문이 있으면 duo chat을 이용하자. 메뉴가 찾기 어렵다. 서비스에 따라서 없을수도 있다.

duo chat

start pipeline

.gitlab-ci.yml 생성 (gitlab-ci.yaml은 동작하지않음)

  • stage

  • job

stage가 생성이 된다. 그리고 job이 생성이 된다.

stage는 tagging system과 비슷하다. 모든것은 Job으로 움직이지만 stage는 job을 그룹화 시키는 역할을 한다.

image: docker:latest
services:
  - docker:dind

variables:
  CS_DEFAULT_BRANCH_IMAGE: $CI_REGISTRY_IMAGE/$CI_DEFAULT_BRANCH:$CI_COMMIT_SHA
  DOCKER_DRIVER: overlay2
  RUNNER_GENERATE_ARTIFACTS_METADATA: 'true'

stages:
  - mybuild
  - mytest

build:
  stage: mybuild
  variables:
    IMAGE: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
  before_script:
    - docker info
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - cd app
    - docker build -t $IMAGE .
  after_script:
    - docker push $IMAGE

test:
  stage: mytest
  image: alpine:latest
  script:
    - echo hello

script, before_script, and after_script

  • before_script: script전에 실행된다. 그리고 script와 같은 shell에서 실행된다.

  • script : runner에 의해서 실행된다. exitcode는 여기에서 리턴된다.

  • after_script : Runs in a separate shell after the before_script / script statements. (다른 쉘에서 실행된다. ) , exitcode 에 대해서는 상관하지 않는다.

test에 코드 추가

test:
  stage: mytest
  image: alpine:latest
  script:
    - echo hello
  after_script:
    - echo "Our race track has been tested!"

실행 순위

stage 순서대로 실행된다.

  • Jobs in the next stage will start after all jobs in the previous stage have completed successfully

  • 다음 단계의 작업은 이전 단계의 모든 작업이 성공적으로 완료된 후 시작됩니다.

Alt text

GitLab Runners

type

  • SSH

  • Shell

  • Virtual Box

  • Parallels

  • Docker

  • Docker Autoscaler (Beta)

  • Docker Machine

  • Kubernetes

  • Custom

tag

tag를 이용해서 runner를 선택할 수 있다.

job:
  tags:
    - myrunner

실행 순서 수정

need를 사용하여 특정 작업 다음에 실행을 할수 있다.

경우에 따라서 stage를 동시에 실행하고 싶을수 있다.

test:
  stage: mytest
  image: alpine:latest
  script:
    - echo hello
  after_script:
    - echo "Our race track has been tested!"
  needs: []

super_fast_test:
  stage: test
  script:
    - echo "If youre not first youre last"
    - return 0
  needs: []

두개의 잡이 다른잡을 기다리지 않고 동시에 실행된다.

Alt text

build가 안끝나도 test가 실행된다. job dependencies가 생겼고 dependency가 없는것을 볼수 잇다.

Directed Acyclic Graph

stage추가하고 다음 코드를 추가해보자.

stages:
  - race

build_car_a:
  stage: mybuild
  script:
    - echo "build_car_a"

build_car_b:
  stage: mybuild
  script:
    - echo "build_car_b"

build_car_c:
  stage: mybuild
  script:
    - echo "build_car_c"

build_car_d:
  stage: mybuild
  script:
    - echo "build_car_d"

build_car_e:
  stage: mybuild
  script:
    - echo "build_car_e"

build_car_f:
  stage: mybuild
  script:
    - echo "build_car_f"

test_car_a:
  stage: mytest
  needs: [build_car_a]
  script:
    - echo "test_car_a"

test_car_b:
  stage: mytest
  needs: [build_car_b]
  script:
    - echo "test_car_b"

test_car_c:
  stage: mytest
  needs: [build_car_c]
  script:
    - echo "test_car_c"

test_car_d:
  stage: mytest
  needs: [build_car_d]
  script:
    - echo "test_car_d"

test_car_e:
  stage: mytest
  needs: [build_car_e]
  script:
    - echo "test_car_e"

test_car_f:
  stage: mytest
  needs: [build_car_f]
  script:
    - echo "test_car_f"

race_car_a:
  stage: race
  needs: [test_car_a]
  script:
    - echo "race_car_a"

race_car_b:
  stage: race
  needs: [test_car_b]
  script:
    - echo "race_car_b"

race_car_c:
  stage: race
  needs: [test_car_c]
  script:
    - echo "race_car_c"

race_car_d:
  stage: race
  needs: [test_car_d]
  script:
    - echo "race_car_d"

race_car_e:
  stage: race
  needs: [test_car_e]
  script:
    - echo "race_car_e"

race_car_f:
  stage: race
  needs: [test_car_f]
  script:
    - echo "race_car_f"
Alt text
Alt text

여기에서 보면 볼수 잇다.

원복하자.

Stageless Pipelines

버전에 따라서 다르지만 기존에는 need는 다른 stage에 job에 적용할수 있었습니다.

이제는 같은 stage에서도 need가 적용됨. Allows “needs” keyword to be used in the same stage

  • 파이프라인을 좀더 효과적으로 만들수 있습니다.

  • 실행순서를 좀더 명확하게 정할수 있습니다.

Available in (All tiers; 14.2+)

Caching Basics

To cache, a GitLab Runner will take the content you cached and store it in GCP Cloud Storage

Cache Execution Order

  1. Pipeline starts.

  2. job A runs.

  3. before_script is executed.

  4. script is executed.

  5. after_script is executed.

  6. cache runs and the vendor/ directory is zipped into cache.zip. This file is then saved in the directory based on the runner’s setting and the cache: key.

  7. job B runs.

  8. The cache is extracted (if found).

  9. before_script is executed.

  10. script is executed.

  11. Pipeline finishes.

why cache?

작업 간에 다운로드한 콘텐츠 공유: 코드의 여러 브랜치에서 수행할 수도 있습니다. 코드 종속성 저장(다음에 다운로드할 때까지 기다릴 필요 없음) 파이프라인 속도 향상

job A:
  stage: mybuild
  script:
    - mkdir vendor/
    - echo "Hello World" > vendor/hello.txt
  cache:
    key: build-cache
    paths:
      - vendor/
  after_script:
    - echo "world"

job B:
  stage: mytest
  script:
    - cat vendor/hello.txt
  cache:
    key: build-cache
    paths:
      - vendor/
Alt text

hello.txt를 다음작업이 받아서 처리할수 있다.

hello world 가 찍히는걸 볼수 있다. 파일을 가져왔다는 뜻이다.

좀더 의미잇는 샘플을 해보자. ruby를 빌드를 먼저해서 그걸 캐시해두고 다음작업에서 가져와서 사용할수 있다.

좀더 의미잇는 샘플을 해보자. ruby를 빌드를 먼저해서 그걸 캐시해두고 다음작업에서 가져와서 사용할수 있다.

# Cache modules in between jobs
cache:
  - key: cache-$CI_COMMIT_REF_SLUG
    fallback_keys:
      - cache-$CI_DEFAULT_BRANCH
      - cache-default
    paths:
      - vendor/ruby
      - Gemfile.lock

npm도 마찬가지이다. 처음부터 다 설치하지 않고 설치된 파일들을 다운받은후 사용하면 빌드 시간을 줄일수 잇다.

Allowing Job Failure (job 실패를 허용)

We need to find a way to configure the pipeline so that even when the unit test job fails, subsequent jobs still execute.

단위 테스트 작업이 실패하더라도 후속 작업이 계속 실행되도록 파이프라인을 구성하는 방법

allow_failure: true - failing job is logged in the pipeline as failed, but does not prevent subsequent jobs from executing

allow_failure 를 사용하면된다.

스크립트 exit 1 을 실패를 리턴한다.

stage에 deploy를 추가한다.allow_failure: true 가 없으면 deploy는 실행되지 않는다.

stages:
  - deploy

super_fast_test:
  stage: mytest
  script:
    - exit 1
  needs: []
  allow_failure: true

deploy:
  stage: deploy
  script:
    - echo "Deploying"
  needs: [super_fast_test]

allow_failure: true 없는 경우

allow_failure: true 있는 경우

rules

rules을 추가

rules:
  - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

맞는 조건에만 실행이 된다.

When is a Job NOT created in a Pipeline?

When is a Job NOT created in a Pipeline?

A job is not included in a pipeline if:

  • None of the rules defined for the job evaluate to true

  • A rule evaluates to true, but has clause of when: never

  • No rules are defined but a when: never clause is specified

다음과 같은 경우 작업은 파이프라인에 포함되지 않습니다:

  • 작업에 대해 정의된 규칙 중 어느 것도 참으로 평가되지 않습니다.

  • 규칙이 참으로 평가되지만 when: never 절이 있습니다.

  • 규칙이 정의되어 있지 않지만 when: never 절이 지정되어 있습니다.

job:
  script: echo "Hello, World!"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: never
    - if: $CI_PIPELINE_SOURCE == "schedule"
      when: never
    - when: on_success

두개의 경우에는 job이 실행되지 않는다.

when: on_success : 이전 작업이 성공했다고 가정하여 작업을 실행하도록 지시합니다. 이줄에 오면 기존 if는 어느것도 만족하지 않을때 여기까지 오게 된다.

when: manual

수동으로 실행하고 싶으면 when: manual 을 추가하면 된다.

화면에서 실행버튼이 나오므로 그걸 누르면된다.

super_fast_test:
  stage: mytest
  script:
    - exit 1
  needs: []
  allow_failure: true

deploy:
  stage: deploy
  script:
    - echo "Deploying"
  needs: [super_fast_test]
  when: manual
click

If $CI_PIPELINE_SOURCE is set to merge_request_event or schedule, the job is executed

CI_PIPELINE_SOURCE가 merge_request_event 또는 스케줄로 설정된 경우 작업이 실행됩니다.

job:
  script: echo "Hello, World!"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_PIPELINE_SOURCE == "schedule"

when for delaying a job run

If used as when: delayed, start_in is also required.

job:
  script: echo "Hello, World!"
  rules:
    - if: $CI_COMMIT_BRANCH == "master"
      when: delayed
      start_in: 3 hours

using changes and if

job:
  script: docker build -t
  rules:
    - if: $VAR == "string value"
      changes:
        - Dockerfile
        - docker/scripts/*
      when: manual

경로중에 파일이 바귀면 실행되도록 할수 있다.

위 내용은 두개의 경로의 파일이 하나라더 바귀면 실행된다. AND를 실행하려면 아래와 같이 하면된다.

changes:
  - Dockerfile AND docker/scripts/*

variables Processing Order

The order of precedence for variables is (from highest to lowest): 변수의 우선 순위는 (높은 것부터 낮은 것) 입니다

  1. CICD pipeline Trigger variables, scheduled pipeline variables, and manual pipeline run variables.

  2. Project-level variables or protected variables.

  3. Group-level variables or protected variables.

  4. Instance-level variables or protected variables.

  5. Inherited environment variables.

  6. YAML-defined job-level variables.

  7. YAML-defined global variables.

  8. Deployment variables.

  9. Predefined environment variables.

Alt text

Stroing with artifacts

build:
  stage: build
  script:
    - echo hi > test.txt
  artifacts:
    paths:
      - test.txt
    expire_in: 1 hour
Alt text

artifacts을 다운로드할수 있습니다.

template

How to get SAST from GitLab

SAST는 Static Application Security Testing의 약자이다.

include:
  - template: Security/SAST.gitlab-ci.yml
sast job: chosen stage does not exist; available stages are .pre, mytest, deploy, .post

add test stage

stages:
  - test

Now that we have SAST lets add a few more security templates to our project to confirm that our code is secure

include:
  - template: Code-Quality.gitlab-ci.yml
Alt text

child process

SAST를 활성화하여 파이프라인을 데모한 후 보안 팀에서 더 많은 스캐너로 자체 파이프라인을 실행하고 있으며 이를 파이프라인과 통합하기를 원한다는 사실을 알려줍니다. 이를 위한 가장 좋은 방법은 하위 파이프라인을 설정하는 것이라고 결정합니다.

전체 코드를 업데이트하자.

image: docker:latest

services:
  - docker:dind

stages:
  - build
  - test

build:
  stage: build
  script:
    - echo hello

new stage 추가

stages:
  - build
  - test
  - extra-security

extra-security 추가. trigger를 사용하고 include를 사용한다.

downstream_security:
  stage: extra-security
  trigger:
    include:
      - local: security-pipeline/security.gitlab-ci.yml

create folder and file

security-pipeline/security.gitlab-ci.yml

image: docker:latest

include:
  - template: Code-Quality.gitlab-ci.yml
  - template: Jobs/Dependency-Scanning.gitlab-ci.yml
  - template: Jobs/SAST.gitlab-ci.yml
  - template: Jobs/Secret-Detection.gitlab-ci.yml

어떤 파이프라인이라도 추가해서 사용할수 있다.

Alt text

Downstream Pipelines

Two types:

  • Parent-child

    • 파이프라인이 같은 프로젝트에 존재

    • 부모 파이프라인과 동일한 프로젝트, 참조 및 커밋 SHA에서 실행됩니다.

    • 기본적으로 파이프라인이 실행되는 참조의 전체 상태에 직접적인 영향을 미치지 않습니다(자식 파이프라인을 트리거할 때 strategy:depend를 사용하지 않는 한).

    • 중첩된 레벨 2개로 제한

  • Multi-project

    • 파이프라인은 여러 프로젝트에 존재합니다.

    • 업스트림(트리거링) 파이프라인은 다운스트림(트리거링) 파이프라인에 대한 제어 권한이 많지 않습니다.

    • 실행 중인 프로젝트의 전체 참조 상태에는 영향을 주지만 트리거 파이프라인의 참조 상태에는 영향을 미치지 않습니다.

    • 독립적이므로 중첩 제한이 없습니다.

Rules & Child Pipelines

Allows you to get creative and make dynamic changes to the current results of your pipelines 창의력을 발휘하여 파이프라인의 현재 결과를 동적으로 변경할 수 있습니다.

Last updated

Was this helpful?