티스토리 뷰

IT/Infra&Cloud

[gcp] Cloud Function(with jenkins)

Hayley Shim 2024. 7. 13. 01:01

안녕하세요, GCP의 Google Cloud의 서버리스 제품 중 Google Cloud Functions에 대해 알아보겠습니다.

 

Cloud Function

Cloud Functions(2세대)는 Google Cloud의 Functions-as-a-Service 제품인 Google Cloud Functions의 다음 버전입니다. 이를 통해 사용자는 동시성, 트래픽 분할, 처리 시간 연장 등 Cloud Run의 주요 이점을 활용할 수 있습니다. 이 새 버전은 Cloud Run 및 Eventarc를 기반으로 하여 성능 및 확장성에 대한 고급 제어 기능을 제공하고 90개가 넘는 이벤트 소스의 함수 런타임 및 트리거에 대한 더 많은 제어 기능을 제공합니다.

Cloud Functions(2세대) 생성 시 Cloud Run 주요 기능 제공

 

 

Cloud Function 제품을 이해하기 위해 Getting started with Cloud Functions (2nd gen)  코드랩을 참고하였습니다.

이 Codelab에서는 HTTP 호출에 응답하고 Pub/Sub 메시지와 Cloud 감사 로그에 의해 트리거되는 Cloud Functions를 만드는 과정을 안내합니다. 실습에 필요한 사전작업을 진행합니다.

 

HTTP Function

HTTP 요청에 응답하는 인증된 Node.js 함수를 생성합니다.

 

Getting started with Cloud Functions (2nd gen)  |  Google Codelabs

In this codelab, you will learn about Google Cloud Functions (2nd gen). More specifically, you will deploy functions that respond to HTTP calls, Pub/Sub messages, Cloud Storage events and Cloud Audit Logs.

codelabs.developers.google.com

 

index.js 파일 생성

const functions = require('@google-cloud/functions-framework');

functions.http('helloWorld', (req, res) => {
  res.status(200).send('HTTP with Node.js in GCF 2nd gen!');
});

 

dependencies를 표기하는 package.json 파일 생성

{
  "name": "nodejs-functions-gen2-codelab",
  "version": "0.0.1",
  "main": "index.js",
  "dependencies": {
    "@google-cloud/functions-framework": "^2.0.0"
  }
}

 

gcloud 명령어로 함수 deploy

gcloud functions deploy nodejs-http-function \
  --gen2 \
  --runtime nodejs16 \
  --entry-point helloWorld \
  --source . \
  --region $REGION \
  --trigger-http \
  --timeout 600s

 

아래 명령어로 함수 테스트  

  gcloud functions call nodejs-http-function \
  --gen2 --region $REGION
  
  HTTP with Node.js in GCF 2nd gen!

 

 

Pub/Sub Function

특정 Topic에 게시된 Pub/Sub 메시지에 의해 트리거되는 Python 함수를 생성합니다.

 

Getting started with Cloud Functions (2nd gen)  |  Google Codelabs

In this codelab, you will learn about Google Cloud Functions (2nd gen). More specifically, you will deploy functions that respond to HTTP calls, Pub/Sub messages, Cloud Storage events and Cloud Audit Logs.

codelabs.developers.google.com

 

Pub/Sub topic 생성

TOPIC=cloud-functions-gen2-topic
gcloud pubsub topics create $TOPIC

 

 

CloudEvent ID가 포함된 메시지를 간단히 기록하는 main.py 파일 생성

import functions_framework

@functions_framework.cloud_event
def hello_pubsub(cloud_event):
   print('Pub/Sub with Python in GCF 2nd gen! Id: ' + cloud_event['id'])

 

dependencies를 표기하는 requirements.txt 생성

functions-framework==3.*

 

아래 명령어로 함수 deploy

gcloud functions deploy python-pubsub-function \
  --gen2 \
  --runtime python39 \
  --entry-point hello_pubsub \
  --source . \
  --region $REGION \
  --trigger-topic $TOPIC

 

gcloud pubsub topics publish $TOPIC --message="Hello World"

messageIds:
- '11707454230388048'

 

 

 

 

 

Cloud Storage Function

Cloud Storage 버킷의 이벤트에 응답하는 Node.js 함수 생성합니다.

 

Cloud Storage events 에 응답하는 index.js 파일 생성

const functions = require('@google-cloud/functions-framework');

functions.cloudEvent('helloStorage', (cloudevent) => {
  console.log('Cloud Storage event with Node.js in GCF 2nd gen!');
  console.log(cloudevent);
});

 

dependencies를 표기하는 package.json 파일 생성

{
  "name": "nodejs-functions-gen2-codelab",
  "version": "0.0.1",
  "main": "index.js",
  "dependencies": {
    "@google-cloud/functions-framework": "^2.0.0"
  }
}

 

Cloud bucket 생성

​​export BUCKET="gs://gcf-gen2-storage-$PROJECT_ID"
gsutil mb -l $REGION $BUCKET

 

함수 deploy

gcloud functions deploy nodejs-storage-function \
  --gen2 \
  --runtime nodejs16 \
  --entry-point helloStorage \
  --source . \
  --region $REGION \
  --trigger-bucket $BUCKET \
  --trigger-location $REGION

 

버킷에 파일 업로드를 통한 함수 테스트

echo "Hello World" > random.txt
gsutil cp random.txt $BUCKET/random.txt

 

아래 명령어로 로그에서 CloudEvent 수신 확인

gcloud functions logs read nodejs-storage-function \
  --region $REGION --gen2 --limit=100 --format "value(log)"

 

 

Cloud Audit Logs Function

 

Getting started with Cloud Functions (2nd gen)  |  Google Codelabs

In this codelab, you will learn about Google Cloud Functions (2nd gen). More specifically, you will deploy functions that respond to HTTP calls, Pub/Sub messages, Cloud Storage events and Cloud Audit Logs.

codelabs.developers.google.com

 

Compute Engine VM 인스턴스가 생성될 때 Cloud 감사 로그 이벤트를 수신하는 Node.js 함수를 생성합니다.

 

Cloud 감사 로그 기능을 사용하려면 Eventarc에 대한 감사 로그를 활성화해야 합니다. 또한 eventarc.eventReceiver 역할이 있는 서비스 계정을 사용해야합니다

 

1. Cloud Audit Logs에서 Compute Engine API

기본 Compute Engine 서비스 계정에 eventarc.eventReceiver IAM 역할 부여

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
  --role roles/eventarc.eventReceiver

 

index.js

- CloudEvent로 래핑된 감사 로그를 수신하는 애플리케이션 코드

- 그런 다음 Compute Engine VM 인스턴스 세부정보를 추출하고 VM 인스턴스에 라벨 설정

 

const { google } = require("googleapis");
var compute = google.compute("v1");

exports.labelVmCreation = async (cloudevent) => {
  var data = cloudevent;

  // in case an event has >1 audit log
  // make sure we respond to the last event
  if (!data.operation.last) {
    console.log("Operation is not last, skipping event");
    return;
  }

  // projects/dogfood-gcf-saraford/zones/us-central1-a/instances/instance-1
  var resourceName = data.protoPayload.resourceName;
  var resourceParts = resourceName.split("/");
  var project = resourceParts[1];
  var zone = resourceParts[3];
  var instanceName = resourceParts[5];
  var username = data.protoPayload.authenticationInfo.principalEmail.split("@")[0];


  console.log(`Setting label username: ${username} to instance ${instanceName} for zone ${zone}`);

  var authClient = await google.auth.getClient({
    scopes: ["https://www.googleapis.com/auth/cloud-platform"]
  });

  // per docs: When updating or adding labels in the API,
  // you need to provide the latest labels fingerprint with your request,
  // to prevent any conflicts with other requests.
  var labelFingerprint = await getInstanceLabelFingerprint(authClient, project, zone, instanceName);

  var responseStatus = await setVmLabel(
    authClient,
    labelFingerprint,
    username,
    project,
    zone,
    instanceName
  );

  // log results of setting VM label
  console.log(JSON.stringify(responseStatus, null, 2));
};

async function getInstanceLabelFingerprint(authClient, project, zone, instanceName) {
  var request = {
    project: project,
    zone: zone,
    instance: instanceName,
    auth: authClient
  };


  var response = await compute.instances.get(request);
  var labelFingerprint = response.data.labelFingerprint;
  return labelFingerprint;
}

async function setVmLabel(authClient, labelFingerprint, username, project, zone, instanceName) {
  var request = {
    project: project,
    zone: zone,
    instance: instanceName,

    resource: {
      labels: { "creator": username },
      labelFingerprint: labelFingerprint
    },

    auth: authClient
  };

  var response = await compute.instances.setLabels(request);
  return response.statusText;
}

 

함수 deploy

gcloud functions deploy gce-vm-labeler \
  --gen2 \
  --runtime nodejs16 \
  --entry-point labelVmCreation \
  --source . \
  --region $REGION \
  --trigger-event-filters="type=google.cloud.audit.log.v1.written,serviceName=compute.googleapis.com,methodName=beta.compute.instances.insert" \
  --trigger-location us-central1

 

 

 

Audit Log function를 테스트하기 위해 Compute Engine VM 생성

 

 

위와 같이 Cloud Audit Log 이벤트가 발생했을 때 VM에 creator 라벨이 생성된 것을 확인했습니다. 

 

 

Jenkins 연동

[참고] Jenkins를 사용하여 GCP Cloud Function 테스트 자동화

테스트 주도 개발 프로세스를 따르는 동안 반복적인 테스트를 통해 진행 상황을 추적해야 합니다. 따라서 견고하고 효율적이며 비용 효율적인 자동화 테스트 프레임워크가 없다면 수동으로 페이로드를 트리거하고 결과를 검증해야 합니다. 수동 테스트는 시간이 더 오래 걸릴 뿐만 아니라 오류가 발생하기 쉽습니다. Jenkins를 오케스트레이션 도구로 사용하여 Cloud Function, Cloud Run, Dataflow와 같은 이벤트를 처리하는 GCP 구성 요소를 테스트하는 데 사용할 수 있습니다.

 

 

 

Jenkins Pipeline 

https://www.jenkins.io/doc/book/pipeline/getting-started/

 

Getting started with Pipeline

Jenkins – an open source automation server which enables developers around the world to reliably build, test, and deploy their software

www.jenkins.io

 

 

GCP와 Jenkins 설정

https://dareplanet.tech/en/insights/how-to-configure-jenkins-with-google-cloud-platform/

 

Google Cloud Platform에서 Jenkins를 설정하기 위한 요구사항

  1. Account on a Jenkins instance*: With administrator permissions.
  2. Account on Google Cloud Platform: Capable of using Compute Engine and create service accounts.
  3. Optional: gcloud command-line tool.

 

Google Cloud Platform 서비스 계정 만들기

gcloud iam service-accounts create jenkins-gce

 

 

서비스 계정에 필요한 역할 할당

export PROJECT=$(gcloud info --format='value(config.project)')
export SA_EMAIL=$(gcloud iam service-accounts list --filter="name:jenkins-gce" \
 --format='value(email)')
gcloud projects add-iam-policy-binding --member serviceAccount:$SA_EMAIL \
 --role roles/compute.instanceAdmin $PROJECT
gcloud projects add-iam-policy-binding --member serviceAccount:$SA_EMAIL \
 --role roles/compute.networkAdmin $PROJECT
gcloud projects add-iam-policy-binding --member serviceAccount:$SA_EMAIL \
 --role roles/iam.serviceAccountUser $PROJECT
 gcloud projects get-iam-policy $PROJECT

 

 

JSON 서비스 계정 키 가져오기

gcloud iam service-accounts keys create --iam-account $SA_EMAIL jenkins-gce.json

 


Cloud Functions 생성

 

 

 

 

Cloud Storage 내 Cloud Functions 소스 경로 확인 

 

 

Google Compute Engine(GCE) 플러그인 설치

Manage Jenkins > Manage Plugins > Available and look for “Google Compute Engine”

Google Compute Engine 플러그인 설치

 

 

Service account credentials setup

 

Manage Jenkins > Manage Credentials > Global > Add Credentials of kind “Google Service Account from private key”.

->  Google Service Account from private key 로 에러 발생 시 아래와 같이 Secret file로 등록해줍니다.

https://stackoverflow.com/questions/45355007/how-to-authenticate-with-a-google-service-account-in-jenkins-pipeline

 

Jenkins Pipeline 실행

 

Groovy 파일 생성

pipeline {
    agent any
        stages {
        stage('Deploy to Cloud Functions') {
            steps {
                withCredentials([file(credentialsId: '${Service Account Credential Name}', variable: 'GCP_SA_KEY')]) {
                    sh 'gcloud auth activate-service-account --key-file=$GCP_SA_KEY'
                    sh 'gcloud config set project ${PROJECT_ID}'
                    sh 'gcloud functions deploy {FUNCTIONS_NAME} --gen2 --runtime=python312 --region=asia-northeast3 --entry-point=hello_http --trigger-http --source=${Cloud Functions Source Directory}'
                }
            }
        }
    }
}

 

${Service Account Credential Name} : Jenkins Credentials에 등록한 GCP Service Account Credential 이름

${Project_ID} : 배포할 GCP 프로젝트의 ID

${FUNCTIONS_NAME} : 배포할 Cloud Functions 이름

${Cloud Functions Source Directory} : Cloud Functions 소스 경로

 

 

Build Test

 

 

Cloud Function 트리거 확인

 

 

 

 

 

참고

https://dareplanet.tech/en/insights/how-to-configure-jenkins-with-google-cloud-platform/

 

How to Configure Jenkins with Google Cloud Platform (GCP) | Dare Planet Technology

In this post, we bring you a complete step-by-step tutorial on how to configure Jenkins with Google Cloud Platform (GCP). We also include a final simulation.

dareplanet.tech

 

https://cloud.google.com/functions/docs/deploy?hl=ko

 

Cloud 함수 배포  |  Cloud Functions Documentation  |  Google Cloud

검색을 단순화하고 문서 이용 환경을 개선하기 위해 1세대 및 2세대 문서가 개별 집합으로 분할됩니다. 의견 보내기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류

cloud.google.com

 

 

ERROR: (gcloud.functions.deploy) Invalid value for [--source]: Provided source directory does not have file [package.json] which is required for [nodejs20]. Did you specify the right source?

 

https://github.com/quarkusio/quarkus/issues/38371

 

Errors when deploying Google Cloud function with CloudEvents using official quarkus guide · Issue #38371 · quarkusio/quarkus

Describe the bug Hi quarkus team, I am following guide on how to deploy Google Cloud Function with CloudEvents using the guide that is provided here. It's correctly described that only gen2 support...

github.com

 

 

How to Deploy GCP Cloud Functions with Cloud Build

https://levelup.gitconnected.com/how-to-deploy-gcp-cloud-functions-with-cloud-build-a35e6010da33

 

How to Deploy GCP Cloud Functions with Cloud Build

Learn to version control your Cloud Functions and deploy them with CI/CD

levelup.gitconnected.com

 

 

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Ok], message=[Permission 'cloudfunctions.functions.get' denied on 'projects/kbshare-security/locations/asia-northeast3/functions/gcp-test']

 

https://stackoverflow.com/questions/61922879/error-gcloud-functions-deploy-responseerror-status-403-code-forbidden

 

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Forbidden]

Basically, I am trying to deploy cloud functions using my cloudbuild.yaml file: Cloudbuild.yaml steps: - name: 'node:10.10.0' id: installing_npm args: ['npm', 'install'] dir: 'API/groups' -...

stackoverflow.com

 

 

 

 

 

 

'IT > Infra&Cloud' 카테고리의 다른 글

[gcp] Cloud Identity SSO 설정  (0) 2024.07.15
[gcp] Cloud Run  (0) 2024.07.13
[gcp] Serverless service(Cloud Function vs Cloud Run)  (0) 2024.07.09
[gcp] Network Connectivity Center(with Lab: NCC)  (0) 2024.07.07
[gcp] Cloud VPN  (0) 2024.07.02
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/01   »
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
글 보관함