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 Functions (1세대 또는 2세대)를 배포하는 방법을 보여줍니다. 이 Codelab에서는 데모 목적으로 인증이 필요하지 않은 공개 Cloud Functions를 사용합니다. 인증이 필요한 다른 Cloud 함수와 마찬가지로 인증된 CMEK 지원 함수를 호출할 수 있습니다.
학습할 내용
- 기존 대칭 키링에서 CMEK 키를 만드는 방법
- Artifact Registry 저장소를 만드는 방법
- Cloud Functions 1세대 및 2세대 모두에서 CMEK를 구성하는 방법
2. 설정 및 요구사항
기본 요건
- Cloud 콘솔에 로그인했습니다
- 이전에 HTTP 트리거 Cloud 함수를 배포했습니다 (적절한 역할 및 API가 사용 설정되어 있는지 확인).
Cloud Shell 활성화
- Cloud Console에서 Cloud Shell 활성화를 클릭합니다.
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 저장소 만들기
이 섹션에서는 Artifact Registry에 CMEK가 사용 설정된 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
그리고 아티팩트 저장소에 저장소를 만들 원칙(예: 현재 활성 계정)에 역할을 부여합니다. 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세대 함수 테스트
curl을 사용하여 함수를 테스트할 수 있습니다.
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를 사용하지만 지원되는 런타임을 사용해도 됩니다.
먼저 디렉터리를 만들고 해당 디렉터리로 이동합니다.
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세대 함수 테스트
다음과 같이 curl을 사용하여 함수를 테스트할 수 있습니다.
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 함수의 소스 탭을 방문하면 보관 파일을 가져오는 중에 오류가 표시됩니다. Cloud Storage에서 소스 코드가 포함된 .zip 파일을 직접 보려고 하면 유사한 오류가 표시됩니다.
또한 Artifact Registry에서 함수의 컨테이너 이미지를 사용할 수 없습니다. 예를 들어 이 컨테이너 이미지를 Cloud Run에 배포하려고 하면 이미지를 찾을 수 없다는 오류가 표시됩니다.
암호화된 리소스의 전체 목록은 CMEK 함수 문서를 참고하세요.
10. 축하합니다
축하합니다. Codelab을 완료했습니다.
학습한 내용
- 기존 대칭 키링에서 CMEK 키를 만드는 방법
- Artifact Registry 저장소를 만드는 방법
- Cloud 함수에 CMEK를 구성하는 방법
자세한 내용
Cloud Functions 및 CMEK에 대한 자세한 내용은 다음 링크를 참고하세요.