1. 소개
개요
Cloud Functions는 경량형 컴퓨팅 솔루션으로, 서버 또는 런타임 환경을 관리할 필요 없이 Cloud 이벤트에 응답하는 것이 유일한 목적인 독립 실행형 함수를 만들기 위해 사용합니다.
Cloud Key Management Service 고객 관리 암호화 키 (CMEK)를 사용하여 Cloud Functions 및 관련 저장 데이터를 보호할 수 있습니다. CMEK로 함수를 배포하면 개발자가 완전히 제어할 수 있는 암호화 키를 사용하여 함수와 연결된 데이터를 보호할 수 있습니다. 이 유형의 암호화를 사용하면 금융 서비스와 같은 특정 업계의 규정 준수 요구사항을 충족할 수 있습니다. 키는 개발자가 소유하며 Google에서 이 키를 제어하지 않으므로 키가 중지되거나 삭제되면 누구도 이러한 암호화 키로 보호되는 데이터에 액세스할 수 없습니다.
Cloud Functions의 경우 CMEK는 다음을 암호화합니다.
- 배포를 위해 업로드되고 Google이 Cloud Storage에 저장하는 빌드 프로세스에서 사용되는 함수 소스 코드
- 함수 빌드 프로세스의 결과물(함수 소스 코드로 빌드된 컨테이너 이미지, 배포된 함수의 각 인스턴스 포함)
- 내부 이벤트 전송 채널의 저장 데이터(1세대만)
암호화되는 데이터에 대한 자세한 내용은 Cloud Functions CMEK 문서를 참고하세요.
빌드할 항목
이 Codelab에서는 CMEK를 사용하여 암호화된 Cloud 함수 (1세대 또는 2세대)를 배포하는 방법을 보여줍니다. 이 Codelab에서는 데모 목적으로 인증이 필요하지 않은 공개 Cloud 함수를 사용합니다. 인증된 CMEK 지원 함수는 인증이 필요한 다른 Cloud 함수와 마찬가지로 호출할 수 있습니다.
학습할 내용
- 기존 대칭 키링에 CMEK 키를 만드는 방법
- Artifact Registry 저장소를 만드는 방법
- 1세대 및 2세대 모두에서 Cloud 함수의 CMEK를 구성하는 방법
2. 설정 및 요구사항
기본 요건
- Cloud 콘솔에 로그인되어 있습니다.
- 이전에 HTTP 트리거 Cloud Functions를 배포한 적이 있습니다 (적절한 역할과 API가 사용 설정되어 있는지 확인).
Cloud Shell 활성화
- Cloud Console에서 Cloud Shell 활성화
를 클릭합니다.

Cloud Shell을 처음 시작하는 경우 설명이 포함된 중간 화면이 제공됩니다. 중간 화면이 표시되면 계속을 클릭합니다.

Cloud Shell을 프로비저닝하고 연결하는 작업은 몇 분이면 끝납니다.

이 가상 머신에는 필요한 개발 도구가 모두 로드되어 있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab에서 대부분의 작업은 브라우저로 수행할 수 있습니다.
Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 해당 프로젝트 ID로 설정된 것을 확인할 수 있습니다.
- Cloud Shell에서 다음 명령어를 실행하여 인증되었는지 확인합니다.
gcloud auth list
명령어 결과
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- Cloud Shell에서 다음 명령어를 실행하여 gcloud 명령어가 프로젝트를 알고 있는지 확인합니다.
gcloud config list project
명령어 결과
[core] project = <PROJECT_ID>
또는 다음 명령어로 설정할 수 있습니다.
gcloud config set project <PROJECT_ID>
명령어 결과
Updated property [core/project].
3. Cloud Functions용 새 키링 및 키 만들기
다음 명령어를 실행하여 Cloud KMS API가 사용 설정되어 있는지 확인합니다.
gcloud services enable cloudkms.googleapis.com
먼저 이 Codelab에서 사용되는 키링 이름, 키 이름, 리전, 기타 변수를 포함하는 환경 변수를 만듭니다.
KEYRING_NAME="keyring-functions" REGION="us-central1" KEY_NAME="key-encrypted-function" PROJECT_ID=$(gcloud config get-value project) PROJECT_NUMBER="$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')" USER_EMAIL="$(gcloud config list account --format "value(core.account)")"
다음으로 Cloud KMS 키 및 키 버전의 루트 리소스인 키링을 만듭니다.
gcloud kms keyrings create $KEYRING_NAME --location $REGION
마지막으로 이제 Cloud KMS 내 새 키링에서 대칭 키를 만들 수 있습니다.
gcloud kms keys create $KEY_NAME --keyring $KEYRING_NAME --location $REGION --purpose "encryption"
4. CMEK가 사용 설정된 Docker 형식 Artifact Registry 저장소 만들기
이 섹션에서는 CMEK가 사용 설정된 Artifact Registry에 Docker 형식 저장소를 만듭니다. 이 키는 Cloud 함수를 배포하는 데 사용된 키와 동일합니다.
먼저 Artifact Registry의 서비스 계정이 필요합니다. 다음 명령어를 실행하여 만들 수 있습니다.
gcloud beta services identity create --service=artifactregistry.googleapis.com --project=$PROJECT_ID
다음 명령어를 사용하여 Artifact Registry 서비스 계정에 CryptoKey 암호화/복호화 IAM 역할 (roles/cloudkms.cryptoKeyEncrypterDecrypter)을 부여하여 키에 대한 권한을 갖도록 합니다.
gcloud kms keys add-iam-policy-binding \ $KEY_NAME --location $REGION --keyring=$KEYRING_NAME \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter
그리고 Artifact Registry에 저장소를 만들 주체(예: 현재 활성 계정)에 역할을 부여합니다. gcloud auth list를 실행하여 현재 활성 계정을 확인할 수 있습니다.
gcloud kms keys add-iam-policy-binding \
$KEY_NAME --location $REGION --keyring=$KEYRING_NAME \
--member user:$USER_EMAIL \
--role roles/cloudkms.cryptoKeyEncrypterDecrypter
이제 CMEK가 사용 설정된 Docker 형식 저장소를 만들 수 있습니다.
참고: 리전은 CMEK 키와 동일한 리전이어야 합니다.
REPO_NAME=my-cmek-encrypted-repo
KEY_FULLPATH=projects/"$PROJECT_ID"/locations/"$REGION"/keyRings/"$KEYRING_NAME"/cryptoKeys/"$KEY_NAME"
gcloud artifacts repositories create $REPO_NAME \
--repository-format=docker \
--location=$REGION \
--kms-key=$KEY_FULLPATH \
--async
다음 명령어를 실행하여 새 Artifact Registry 저장소를 확인할 수 있습니다.
gcloud artifacts repositories describe $REPO_NAME --location=$REGION
5. 서비스 계정에 키에 대한 액세스 권한 부여 (2세대)
이 섹션에서는 2세대 함수의 서비스 계정 만들기를 다룹니다. 1세대 함수를 만드는 경우 다음 섹션으로 진행하세요.
CryptoKey 암호화/복호화 IAM 역할 (roles/cloudkms.cryptoKeyEncrypterDecrypter)을 부여하여 여러 서비스 에이전트가 키에 액세스할 수 있도록 해야 합니다. 이러한 서비스 에이전트는 Cloud Storage에 저장된 소스 코드에 액세스하고, Artifact Registry의 CMEK 보호 저장소에 함수 이미지를 저장하고, CMEK 암호화 Cloud 함수를 배포하는 데 사용됩니다.
2세대 함수 단계
- Cloud Run 서비스 에이전트에 키에 대한 액세스 권한을 부여합니다.
CLOUDRUN_SA=service-$PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$CLOUDRUN_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- Eventarc 서비스 에이전트에 키에 대한 액세스 권한을 부여합니다.
EVENTARC_SA=service-$PROJECT_NUMBER@gcp-sa-eventarc.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$EVENTARC_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- Artifact Registry 서비스 에이전트에 키에 대한 액세스 권한을 부여합니다.
AR_SA=service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$AR_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- Cloud Storage 서비스 에이전트에 키에 대한 액세스 권한을 부여합니다.
STORAGE_SA=service-$PROJECT_NUMBER@gs-project-accounts.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$STORAGE_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
다음 섹션에서는 CMEK로 암호화된 함수를 만들고 배포하는 방법을 알아봅니다.
6. 서비스 계정에 키에 대한 액세스 권한 부여 (1세대)
이 섹션에서는 1세대 함수의 서비스 계정 만들기를 다룹니다. 이전에 2세대 함수용 서비스 계정을 만든 경우 다음 섹션으로 진행하세요.
CryptoKey 암호화/복호화 IAM 역할 (roles/cloudkms.cryptoKeyEncrypterDecrypter)을 부여하여 여러 서비스 에이전트가 키에 액세스할 수 있도록 해야 합니다. 이러한 서비스 에이전트는 Cloud Storage에 저장된 소스 코드에 액세스하고, Artifact Registry의 CMEK 보호 저장소에 함수 이미지를 저장하고, CMEK 암호화 Cloud 함수를 배포하는 데 사용됩니다.
1세대 함수 단계
- Cloud Functions 서비스 에이전트에 키에 대한 액세스 권한을 부여합니다.
FUNCTION_SA=service-$PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$FUNCTION_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- Artifact Registry 서비스 에이전트에 키에 대한 액세스 권한을 부여합니다.
AR_SA=service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$AR_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- Cloud Storage 서비스 에이전트에 키에 대한 액세스 권한을 부여합니다.
STORAGE_SA=service-$PROJECT_NUMBER@gs-project-accounts.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$STORAGE_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
다음 섹션에서는 CMEK로 암호화된 함수를 만들고 배포하는 방법을 알아봅니다.
7. CMEK 암호화 함수 (2세대) 만들기
이 섹션에서는 2세대 함수를 만드는 방법을 설명합니다. 다음 섹션에서 1세대 안내를 확인하세요.
이제 CMEK가 사용 설정된 Artifact Registry 저장소를 구성하고 Cloud Functions에 키에 대한 액세스 권한을 부여했으므로 CMEK 키를 사용하여 암호화된 함수를 배포할 수 있습니다.
2세대 함수 단계:
함수의 소스 코드 만들기
이 Codelab에서는 Node.js를 사용하지만 지원되는 런타임을 사용할 수 있습니다.
먼저 디렉터리를 만들고 해당 디렉터리로 cd합니다.
mkdir ~/cmek-function-2ndgen && cd $_
그런 다음 package.json 파일을 만듭니다.
touch package.json
echo '{
"dependencies": {
"@google-cloud/functions-framework": "^2.1.0"
}
}
' > package.json
다음으로 index.js 소스 파일을 만듭니다.
touch index.js
echo 'const functions = require("@google-cloud/functions-framework");
functions.http("helloWorld", (req, res) => {
res.send(`Hello ${req.query.name || req.body.name || "World"}!`);
});' > index.js
CMEK 암호화를 사용하여 2세대 Cloud 함수 배포
참고: 아래 예시에서는 현재 디렉터리의 소스를 사용하여 함수를 배포하는 방법을 보여줍니다. 함수의 소스 코드와 동일한 디렉터리에 있는지 확인합니다.
FUNCTION_NAME=protect-me-cmek-2ndgen ENTRY_POINT=helloWorld REPO_FULLPATH=projects/"$PROJECT_ID"/locations/"$REGION"/repositories/$REPO_NAME gcloud beta functions deploy $FUNCTION_NAME \ --gen2 \ --region $REGION \ --kms-key $KEY_FULLPATH \ --docker-repository $REPO_FULLPATH \ --source . \ --trigger-http \ --allow-unauthenticated \ --runtime nodejs16 \ --entry-point $ENTRY_POINT
다음 명령어를 실행하여 결과 출력에서 CMEK 키를 확인할 수 있습니다.
gcloud functions describe $FUNCTION_NAME –region $REGION | grep kmsKeyName
2세대 함수 테스트
컬링하여 함수를 테스트할 수 있습니다.
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --region $REGION --format='get(serviceConfig.uri)')" curl $FUNCTION_URL
그러면 다음과 같은 결과가 표시됩니다.
Hello World!
암호화 키가 사용 설정되어 있는 한 함수는 호출자에게 성공을 반환합니다. 하지만 암호화 키가 사용 중지되면 호출자에게 오류가 표시됩니다.
다음 섹션에서는 키가 사용 중지된 후 함수를 호출할 때 발생하는 상황을 살펴봅니다.
8. CMEK로 암호화된 함수 만들기 (1세대)
이 섹션에서는 1세대 함수를 만드는 방법을 설명합니다. 이전에 2세대 함수를 만든 경우 다음 섹션으로 진행하세요.
이제 CMEK가 사용 설정된 Artifact Registry 저장소를 구성하고 Cloud Functions에 키에 대한 액세스 권한을 부여했으므로 CMEK 키를 사용하여 암호화된 함수를 배포할 수 있습니다.
1세대 함수 단계:
1세대 함수의 소스 코드 만들기
이 Codelab에서는 Node.js를 사용하지만 지원되는 런타임을 사용할 수 있습니다.
먼저 디렉터리를 만들고 해당 디렉터리로 cd합니다.
mkdir ~/cmek-function-1stgen && cd $_
그런 다음 package.json 파일을 만듭니다.
touch package.json
echo '{
"name": "function-cmek-codelab",
"version": "0.0.1"
}' > package.json
그런 다음 index.js 소스 파일을 만듭니다.
touch index.js
echo "exports.helloWorld = (req, res) => {
let message = req.query.message || req.body.message || 'Hello World!';
res.status(200).send(message);
};" > index.js
CMEK 암호화를 사용하여 1세대 Cloud 함수 배포
참고: 아래 예시에서는 현재 디렉터리의 소스를 사용하여 함수를 배포하는 방법을 보여줍니다. 함수의 소스 코드와 동일한 디렉터리에 있는지 확인합니다.
FUNCTION_NAME=protect-me-cmek-1stgen ENTRY_POINT=helloWorld REPO_FULLPATH=projects/"$PROJECT_ID"/locations/"$REGION"/repositories/$REPO_NAME gcloud functions deploy $FUNCTION_NAME \ --region $REGION \ --kms-key $KEY_FULLPATH \ --docker-repository $REPO_FULLPATH \ --source . \ --trigger-http \ --allow-unauthenticated \ --runtime nodejs16 \ --entry-point $ENTRY_POINT
다음 명령어를 실행하여 결과 출력에서 CMEK 키를 확인할 수 있습니다.
gcloud functions describe $FUNCTION_NAME –region $REGION | grep kmsKeyName
1세대 함수 테스트
컬링하여 함수를 테스트할 수 있습니다.
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --region $REGION --format='get(httpsTrigger.url)')" curl $FUNCTION_URL
그러면 다음과 같은 결과가 표시됩니다.
Hello World!
암호화 키가 사용 설정되어 있는 한 함수는 호출자에게 성공을 반환합니다. 하지만 암호화 키가 사용 중지되면 호출자에게 오류가 표시됩니다.
다음 섹션에서는 키가 사용 중지된 후 함수를 호출할 때 발생하는 상황을 보여줍니다.
9. 암호화 키가 사용 중지된 CMEK 암호화 함수 호출
이 마지막 섹션에서는 키를 무효화하고 함수를 다시 호출하여 결과 오류를 확인합니다.
암호화 키 사용 중지
이 명령어를 실행하여 키를 사용 중지할 수 있습니다. 이 Codelab에서는 키 버전을 하나만 생성하므로 버전 1을 사용 중지합니다.
gcloud kms keys versions disable 1 \
--key=$KEY_NAME \
--keyring=$KEYRING_NAME \
--location=$REGION
결과 정보가 표시됩니다.
algorithm: GOOGLE_SYMMETRIC_ENCRYPTION createTime: '2023-04-11T03:30:49.111832653Z' generateTime: '2023-04-11T03:30:49.111832653Z' name: projects/dogfood-gcf-saraford/locations/us-central1/keyRings/myKeyRing/cryptoKeys/encrypted-function/cryptoKeyVersions/1 protectionLevel: SOFTWARE state: DISABLED
사용 중지된 키로 함수 호출
이제 함수를 다시 curl합니다.
curl $FUNCTION_URL
이번에는 Hello World 응답을 받지 못합니다.
Cloud 함수의 로그에 다음이 표시됩니다.
User's CMEK key has been disabled. CMEK key: projects/<PROJECT-NAME>/locations/us-central1/keyRings/myKeyRing/cryptoKeys/encrypted-function
CMEK 키가 사용 중지된 경우 리소스 보기 시도
이 섹션에서는 CMEK 키가 사용 중지될 때 사용할 수 없게 되는 리소스를 보여줍니다.
- 함수 소스 코드
- 소스 코드에서 빌드된 컨테이너 이미지
예를 들어 Cloud 함수의 소스 탭을 방문하면 보관 파일을 가져오는 중에 오류가 표시됩니다. 소스 코드가 포함된 .zip 파일을 Cloud Storage에서 직접 보려고 하면 유사한 오류가 표시됩니다.

또한 Artifact Registry에서 함수의 컨테이너 이미지를 사용할 수 없습니다. 예를 들어 해당 컨테이너 이미지를 Cloud Run에 배포하려고 하면 이미지를 찾을 수 없다는 오류가 표시됩니다.
암호화된 리소스의 전체 목록은 CMEK 함수 문서를 참고하세요.
10. 축하합니다
축하합니다. Codelab을 완료했습니다.
학습한 내용
- 기존 대칭 키링에 CMEK 키를 만드는 방법
- Artifact Registry 저장소를 만드는 방법
- Cloud Functions에서 CMEK를 구성하는 방법
자세한 내용
Cloud Functions 및 CMEK에 대한 자세한 내용은 다음 링크를 참고하세요.