나만의 알리미 만들기

Cloud Build는 Slack 또는 SMTP 서버와 같은 원하는 채널에 알림을 전송하여 빌드 상태에 대한 업데이트를 알릴 수 있습니다. Cloud Build는 현재 cloud-build-notifiers 저장소에서 Slack, SMTP, BigQuery, HTTP용 배포 가능한 알리미 이미지를 제공하고 유지관리합니다.

cloud-build-notifiers 저장소에서 제공된 라이브러리를 사용하여 다른 채널에 알림 업데이트를 보내는 나만의 알리미를 만들 수 있습니다. 이 페이지에서는 나만의 알리미를 만드는 방법을 설명합니다.

시작하기 전에

  • Cloud Build, Cloud Run, Pub/Sub, and Secret Manager API를 사용 설정합니다.

    API 사용 설정

  • Go 프로그래밍 언어를 설치합니다.

  • Cloud SDK를 설치합니다.

설정

  1. 머신에서 터미널 창을 엽니다.

  2. cloud-build-notifiers 저장소를 클론하고 이동합니다.

      git clone https://github.com/GoogleCloudPlatform/cloud-build-notifiers.git && cd cloud-build-notifiers
    
  3. 나만의 알리미에 대한 디렉터리를 추가하고 디렉터리로 이동합니다. 여기서 DIRECTORY_NAME은 디렉터리의 이름입니다.

      mkdir DIRECTORY_NAME && cd DIRECTORY_NAME
    
  4. 새 디렉터리에서 Go 모듈을 초기화합니다. 여기서 DIRECTORY_NAME은 새 디렉터리의 이름입니다.

      go mod init github.com/GoogleCloudPlatform/cloud-build-notifiers/DIRECTORY_NAME
    

    이제 디렉터리에 go.mod 파일이 표시됩니다.

  5. go.mod 파일에 다음 줄을 추가하여 최신 버전의 알리미를 사용합니다.

     replace github.com/GoogleCloudPlatform/cloud-build-notifiers/lib/notifiers => ../lib/notifiers
    

이제 종속 항목이 설정되었으며 나만의 알리미를 만들 수 있습니다.

나만의 알리미 만들기

cloud-build-notifiers에는 lib/notifiers 디렉터리가 포함됩니다. lib/notifiers 디렉터리에 notifier.go라는 파일이 표시됩니다. 이 파일에는 나만의 알리미를 만드는 데 사용할 수 있는 프레임워크가 포함되어 있습니다.

기본 파일에서 알리미를 만들려면 두 가지 방법을 정의해야 합니다.

  1. 새 디렉터리에 main.go라는 파일을 만듭니다.

  2. main.go에서 알리미 라이브러리 프레임워크 및 다른 모든 종속 항목을 가져옵니다.

    package main
    
    import (
            "context"
            "fmt"
    
            cbpb "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1"
            log "github.com/golang/glog"
            "github.com/GoogleCloudPlatform/cloud-build-notifiers/lib/notifiers"
            "github.com/golang/protobuf/proto"
    )
  3. 알리미의 기본 메서드를 정의하세요. 이 예시에서 logger는 알리미의 이름입니다.

    func main() {
        if err := notifiers.Main(new(logger)); err != nil {
            log.Fatalf("fatal error: %v", err)
        }
    }

    main 메서드는 알리미 바이너리를 설정하는 데 사용되는 notifier.go 파일에 정의된 Main 메서드를 사용합니다.

  4. 인터페이스의 변수를 정의해주는 알리미의 구조를 정의하세요. 이 예시에서 logger는 알리미의 이름입니다. 예를 들면 다음과 같습니다.

    type logger struct {
        filter notifiers.EventFilter
    }

그런 후 알리미 기능을 추가합니다. 알리미 인터페이스는 다음 두 가지 방법으로 정의됩니다.

  • SetUp: SetUp 메서드는 구성을 수락하고, 보안 비밀을 가져오고, 구성에서 지정된 필터를 가져와서 알림을 전송하는 데 사용할 수 있는 Common Expression Language 조건자로 저장합니다. CEL에 대한 자세한 내용은 cel-spec 저장소를 참조하세요.
  • SendNotification: SendNotification 메서드는 원하는 채널 또는 서비스로 알림을 보내는 데 사용됩니다.

    알리미의 정의는 notifier.goGo 문서에서 확인할 수 있습니다.

    아래 예시에서 알리미 인터페이스는 빌드 로그를 출력하기 위해 알리미의 이름인 logger와 함께 SetUpSendNotification 메서드를 사용하여 정의합니다.

    func (h *logger) SetUp(_ context.Context, cfg *notifiers.Config, _ notifiers.SecretGetter, _ notifiers.BindingResolver) error {
        prd, err := notifiers.MakeCELPredicate(cfg.Spec.Notification.Filter)
         if err != nil {
            return fmt.Errorf("failed to create CELPredicate: %w", err)
         }
        h.filter = prd
        return nil
    }
    
    func (h *logger) SendNotification(ctx context.Context, build *cbpb.Build) error {
        // Include custom functionality here.
        // This example logs the build.
        if h.filter.Apply(ctx, build) {
            log.V(1).Infof("printing build\n%s", proto.MarshalTextString(build))
        } else {
            log.V(1).Infof("build (%q, %q) did NOT match CEL filter", build.ProjectId, build.Id)
        }
    
        return nil
    }

    최종 main.go 파일은 다음 파일과 유사합니다. 이 예시에서 logger는 알리미의 이름으로 사용됩니다.

    package main
    
    import (
            "context"
            "fmt"
    
            cbpb "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1"
            log "github.com/golang/glog"
            "github.com/GoogleCloudPlatform/cloud-build-notifiers/lib/notifiers"
            "github.com/golang/protobuf/proto"
    )
    
    func main() {
        if err := notifiers.Main(new(logger)); err != nil {
            log.Fatalf("fatal error: %v", err)
        }
    }
    
    type logger struct {
        filter notifiers.EventFilter
    }
    
    func (h *logger) SetUp(_ context.Context, cfg *notifiers.Config, _ notifiers.SecretGetter, _ notifiers.BindingResolver) error {
        prd, err := notifiers.MakeCELPredicate(cfg.Spec.Notification.Filter)
         if err != nil {
            return fmt.Errorf("failed to create CELPredicate: %w", err)
         }
        h.filter = prd
        return nil
    }
    
    func (h *logger) SendNotification(ctx context.Context, build *cbpb.Build) error {
        // Include custom functionality here.
        // This example logs the build.
        if h.filter.Apply(ctx, build) {
            log.V(1).Infof("printing build\n%s", proto.MarshalTextString(build))
        } else {
            log.V(1).Infof("build (%q, %q) did NOT match CEL filter", build.ProjectId, build.Id)
        }
    
        return nil
    }

    이제 알리미를 정의했으므로 아래 단계를 따라 알리미를 구성할 수 있습니다.

알림 구성

  1. 알리미를 구성하고 빌드 이벤트로 필터링하도록 알리미 구성 파일을 작성합니다.

    다음 알리미 구성 파일 예시에서 filter 필드는 사용 가능한 변수 build와 함께 CEL을 사용하여 SUCCESS 상태의 빌드 이벤트를 필터링합니다.

    apiVersion: cloud-build-notifiers/v1
    kind: YourNotifier
    metadata:
      name: logging-sample
    spec:
      notification:
        filter: build.status == Build.Status.SUCCESS

    각 항목의 의미는 다음과 같습니다.

    • logging-sample은 알리미의 이름입니다.

    필터링할 수 있는 추가 필드는 빌드 리소스를 참조하세요. 추가적인 필터링 예시에 대해서는 CEL을 사용하여 빌드 이벤트 필터링을 참조하세요.

  2. 알리미 구성 파일을 Cloud Storage 버킷에 업로드합니다.

    1. Cloud Storage 버킷이 없으면 다음 명령어를 실행하여 버킷을 만듭니다. 여기서 BUCKET_NAME은 버킷에 지정할 이름으로, 이름 지정 요구사항이 적용됩니다.

      gsutil mb gs://BUCKET_NAME/
      
    2. 버킷에 알리미 구성 파일을 업로드합니다.

      gsutil cp CONFIG_FILE_NAME gs://BUCKET_NAME/CONFIG_FILE_NAME
      

      각 항목의 의미는 다음과 같습니다.

      • BUCKET_NAME은 버킷의 이름입니다.
      • CONFIG_FILE_NAME은 구성 파일의 이름입니다.
  3. 알리미를 빌드하고 배포합니다.

    1. logging-sample에 대해 Dockerfile을 만듭니다.

      
      FROM golang AS build-env
      COPY . /go-src/
      WORKDIR /go-src/
      RUN go build -o /go-app .
      
      # From the Cloud Run docs:
      # https://cloud.google.com/run/docs/tutorials/pubsub#looking_at_the_code
      # Use the official Debian slim image for a lean production container.
      # https://hub.docker.com/_/debian
      # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
      FROM debian:buster-slim
      RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
          ca-certificates && \
          rm -rf /var/lib/apt/lists/*
      
      FROM gcr.io/distroless/base
      COPY --from=build-env /go-app /
      ENTRYPOINT ["/go-app", "--v=1", "--alsologtostderr"]
      
    2. 다음 cloudbuild.yaml 파일을 사용하여 알리미를 빌드하고 배포합니다.

      steps:
      - # Build the binary and put it into the builder image.
        name: gcr.io/cloud-builders/docker
        args: ['build', '--tag=gcr.io/$PROJECT_ID/logging-sample', '.']
      
      - # Push the container image to Container Registry
        name: gcr.io/cloud-builders/docker
        args: ['push', 'gcr.io/$PROJECT_ID/logging-sample']
      
      - # Deploy to Cloud Run
        name: google/cloud-sdk
        args:
          - gcloud
          - run
          - deploy
          - logging-sample-notifier
          - --platform=managed
          - --region=us-central1
          - --image=gcr.io/$PROJECT_ID/logging-sample
          - --no-allow-unauthenticated
          - --update-env-vars=CONFIG_PATH=${_CONFIG_PATH}
      
      # Push the image with tags.
      images:
      - gcr.io/$PROJECT_ID/logging-sample

      각 항목의 의미는 다음과 같습니다.

      • _CONFIG_PATH는 알리미 구성 경로로서 예를 들면 gs://BUCKET_NAME/CONFIG_FILE_NAME.yaml입니다.

    cloudbuild.yaml을 실행하려면 알리미 경로를 대체 변수로 전달하세요.

     gcloud builds submit .  --substitutions=_CONFIG_PATH=gs://BUCKET_NAME/CONFIG_FILE_NAME
    
  4. 프로젝트에서 인증 토큰을 만들도록 Pub/Sub 권한을 부여합니다.

     gcloud projects add-iam-policy-binding PROJECT_ID \
       --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
       --role=roles/iam.serviceAccountTokenCreator
    

    각 항목의 의미는 다음과 같습니다.

    • PROJECT_ID는 클라우드 프로젝트의 ID입니다.
    • PROJECT_NUMBER는 클라우드 프로젝트 번호입니다.
  5. Pub/Sub 구독 ID를 나타내는 서비스 계정을 만듭니다.

    gcloud iam service-accounts create cloud-run-pubsub-invoker \
      --display-name "Cloud Run Pub/Sub Invoker"
    

    cloud-run-pubsub-invoker 또는 Google Cloud 프로젝트 내의 고유 이름을 사용할 수 있습니다.

  6. cloud-run-pubsub-invoker 서비스 계정에 Cloud Run Invoker 권한을 부여합니다.

    gcloud run services add-iam-policy-binding SERVICE_NAME \
       --member=serviceAccount:cloud-run-pubsub-invoker@PROJECT_ID.iam.gserviceaccount.com \
       --role=roles/run.invoker
    

    각 항목의 의미는 다음과 같습니다.

    • SERVICE_NAME은 이미지를 배포할 Cloud Run 서비스의 이름입니다.
    • PROJECT_ID는 클라우드 프로젝트의 ID입니다.
  7. Pub/Sub API를 사용 설정하면 Pub/Sub 주제 페이지에서 자동으로 생성된 cloud-builds 주제가 표시됩니다. cloud-builds 주제가 표시되지 않으면 다음 명령어를 실행하여, 알리미의 빌드 업데이트 메시지를 수신할 주제를 수동으로 만듭니다.

    gcloud pubsub topics create cloud-builds
    
  8. 알리미에 대해 Pub/Sub 푸시 구독자를 만듭니다.

     gcloud pubsub subscriptions create SUBSCRIBER_ID \
       --topic=cloud-builds \
       --push-endpoint=SERVICE_URL \
       --push-auth-service-account=cloud-run-pubsub-invoker@PROJECT_ID.iam.gserviceaccount.com
    

    각 항목의 의미는 다음과 같습니다.

    • SUBSCRIBER_ID는 구독에 지정하려는 이름입니다.
    • SERVICE_URL은 Cloud Run에서 생성된 새 서비스에 대한 URL입니다.
    • PROJECT_ID는 클라우드 프로젝트의 ID입니다.

Cloud Build 프로젝트 알림이 이제 설정되었습니다. 다음에 빌드를 호출하면 빌드가 구성한 필터와 일치할 경우 채널에 알림이 전송됩니다.

알림 테스트

이 가이드에 사용된 예시의 알림 기능을 테스트하려면 gcloud builds submit 명령어를 실행하여 빌드를 호출할 수 있습니다.

다음 예시에서는 success.yaml을 구성 경로로 지정합니다. 이 명령어를 실행하면 최소한의 성공한 빌드를 얻게 됩니다. 또한 빌드 로그의 출력도 볼 수 있어야 합니다.

 gcloud builds submit --no-source --config=success.yaml

여기서 success.yaml은 다음과 같습니다.

 steps:
 - name: busybox
   args: ["true"]

다음 예시에서는 failure.yaml을 구성 경로로 지정합니다. 이 명령어를 실행하면 빌드가 실패하게 됩니다. 빌드 로그의 출력이 표시되는 대신 소스에 지정된 CEL 필터와 일치하는 항목이 없다는 출력이 표시됩니다.

gcloud builds submit --no-source --config=failure.yaml

여기서 failure.yaml은 다음과 같습니다.

 steps:
 - name: busybox
   args: ["false"]

Cloud Run 서비스 로그에 출력을 로깅하는 것 이외의 다른 작업을 수행하도록 구성된 알리미를 만든 경우 gcloud builds submit 명령어를 실행하여 알림 기능을 테스트할 수도 있습니다. 빌드와 관련된 오류를 검사하려면 서비스의 Cloud Run 로그를 확인합니다. 자세한 내용은 Cloud Run에서 로그 보기를 참조하세요.

다음 단계