GCP 계정 설정
GCP 계정 설정
GCP 계정을 생성하고 CloudXper Management Platform에서 해당 계정을 사용하기 위한 API 활성화 및 비용을 설정합니다.
Step1. 계정 생성
GCP 웹사이트에 접속하여 계정을 생성합니다.
Step2. Service Account 생성
GCP 계정 인증 정보를 위한 Service account를 생성합니다.
GCP Console > Identity > Service Accounts
Step2.1. 권한 부여
Option1. 단일 계정
Service account 생성 시 viewer 권한을 부여합니다.
만약 Viewer 역할 대신 필요 최소 권한만 부여하려면, 아래 Permission List 목록을 참고하여 역할(Custom Role)을 생성한 뒤 해당 역할을 부여합니다.
Inventory Permission List
bigquery.capacityCommitments.list
bigquery.datasets.get
bigquery.transfers.get
cloudscheduler.jobs.list
cloudscheduler.locations.list
cloudsql.instances.list
compute.addresses.list
compute.backendServices.list
compute.commitments.list
compute.disks.list
compute.firewalls.list
compute.forwardingRules.list
compute.healthChecks.list
compute.images.list
compute.instanceGroups.get
compute.instanceGroups.list
compute.instanceTemplates.list
compute.instances.list
compute.interconnects.list
compute.networks.list
compute.routers.list
compute.routes.list
compute.snapshots.list
compute.subnetworks.list
compute.targetHttpProxies.list
compute.targetHttpsProxies.list
compute.targetPools.list
compute.targetSslProxies.list
compute.targetTcpProxies.list
compute.targetVpnGateways.list
compute.urlMaps.list
compute.vpnGateways.list
compute.vpnTunnels.list
container.clusters.list
container.nodes.list
dns.managedZones.list
dns.resourceRecordSets.list
file.backups.list
file.instances.list
iam.roles.list
iam.serviceAccounts.list
logging.views.access
memcache.instances.list
monitoring.timeSeries.list
pubsub.snapshots.list
pubsub.subscriptions.list
pubsub.topics.list
recommender.bigqueryCapacityCommitmentsRecommendations.list
recommender.computeImageIdleResourceRecommendations.list
redis.instances.list
resourcemanager.projects.getIamPolicy
storage.buckets.list
storagetransfer.agentpools.list
storagetransfer.jobs.listOption2. Organization내 멤버 추가
Organization 으로 계정을 관리할 경우, 아래 이미지와 같이 Project 선택하는 화면에서 Organization을 선택이 가능합니다.
Organization에 속한 Service Account인 경우, 'ADD Another Role'을 사용하여 'Role'에 Editor, Folder Viewer, Organization Viewer 를 선택합니다.
gcloud shell script를 통한 Service Account 생성
Step2.1 Service Account 생성의 Option1 방식의 경우, 아래의 gcloud shell script를 사용하실 경우 좀 더 손쉽게 작업이 가능합니다.
(후속 Step용 gcloud shell script와 연속성이 있으므로, 이 방법을 사용하실 경우 나머지 Step도 gcloud shell script로 작업을 하시길 추천드립니다)
=> Service Account의 이름을 cxp-collector-sa로 지정하여 작업한 스크립트임
# vi 00_create_service_account.sh 하여 파일 생성
아래의 내용을 스크립트에 넣고 저장
#!/usr/bin/env bash set -euo pipefail need() { command -v "$1" >/dev/null 2>&1 || { echo "[ERR] '$1' not found"; exit 1; }; } need gcloud # ---- Inputs: prefer ENV, then gcloud config ---- PROJECT_ID="${PROJECT_ID:-$(gcloud config get-value project 2>/dev/null || true)}" PROJECT_ID="${PROJECT_ID:-}" SA_ID="${SA_ID:-cxp-collector-sa}" SA_DISPLAY_NAME="${SA_DISPLAY_NAME:-CloudXper Federated SA}" PROJECT_ROLES_CSV="${PROJECT_ROLES:-roles/viewer}" # comma-separated roles if [[ -z "${PROJECT_ID}" ]]; then echo "[ERR] PROJECT_ID is empty. Run 'gcloud config set project <ID>' or provide via ENV." >&2 exit 1 fi echo "[INFO] Project: ${PROJECT_ID}" gcloud projects describe "${PROJECT_ID}" >/dev/null SA_EMAIL="${SA_ID}@${PROJECT_ID}.iam.gserviceaccount.com" # ---- Helpers: wait for SA existence & retry role binding ---- wait_for_sa() { local email="$1" max_wait="${2:-90}" waited=0 echo "[INFO] Waiting for SA to propagate: ${email} (timeout ${max_wait}s)" until gcloud iam service-accounts describe "${email}" --project="${PROJECT_ID}" >/dev/null 2>&1; do sleep 3 waited=$((waited+3)) if (( waited >= max_wait )); then echo "[ERR] SA did not become visible within ${max_wait}s: ${email}" >&2 return 1 fi done echo "[INFO] SA is visible." } bind_role_with_retry() { local role="$1" email="$2" local tries=0 max=6 while (( tries < max )); do # Do NOT let 'set -e' abort here; catch exit code and loop. if gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:${email}" \ --role="${role}" \ --quiet >/dev/null; then echo "[INFO] Granted project role: ${role} → ${email}" return 0 fi tries=$((tries+1)) local sleep_s=$((2 ** tries)) # exponential backoff: 2,4,8,16,32,64 echo "[WARN] Role bind failed (attempt ${tries}/${max}); retrying in ${sleep_s}s..." sleep "${sleep_s}" # Re-check SA visibility each iteration gcloud iam service-accounts describe "${email}" --project="${PROJECT_ID}" >/dev/null 2>&1 || true done echo "[ERR] Failed to grant role after ${max} attempts: ${role} → ${email}" >&2 return 1 } # ---- Create SA if not exists ---- if gcloud iam service-accounts describe "${SA_EMAIL}" --project="${PROJECT_ID}" >/dev/null 2>&1; then echo "[INFO] Service Account exists: ${SA_EMAIL}" else echo "[INFO] Creating Service Account: ${SA_EMAIL}" gcloud iam service-accounts create "${SA_ID}" \ --project="${PROJECT_ID}" \ --display-name="${SA_DISPLAY_NAME}" fi # Ensure SA is globally visible before binding roles wait_for_sa "${SA_EMAIL}" 90 # ---- Grant project-level roles (least privilege) ---- IFS=',' read -r -a ROLES <<< "${PROJECT_ROLES_CSV}" for ROLE in "${ROLES[@]}"; do ROLE_TRIM="$(echo "${ROLE}" | xargs)" [[ -z "${ROLE_TRIM}" ]] && continue bind_role_with_retry "${ROLE_TRIM}" "${SA_EMAIL}" done echo "[OK] Service Account ready: ${SA_EMAIL}" echo " Roles applied: ${PROJECT_ROLES_CSV}"# bash 00_create_service_account.sh 수행
Step2.2. 인증 설정
CloudXper 애플리케이션이 클라우드 계정의 리소스 수집 등 권한이 부여된 태스크를 수행하기 위해서 ,
생성한 서비스 계정로 인증 및 인가에 필요한 인증을 설정합니다.
과거에는 인증 키 방식이나 Impersonated 방식도 지원하였으나, 현재는 보안성 및 작업 일관성 확보를 위해 ‘워크로드 아이텐티티 제휴 (WIF)’방식으로만 작업을 권고드립니다.
워크로드 아이덴티티 제휴 (Workload Identity Federation)
IAM & Admin에 Workload Identity Federation 메뉴에서 Identity Pool/AWS Provider를 설정합니다.
Workload Identity Pool 생성
Google Cloud에 접근 허용하려는 AWS Workloads의 교차 인증을 위한 Identity Pool 정보를 생성합니다
AWS Provider 설정
Workloads에 대한 인증 제공자로 AWS를 설정합니다.CloudXper의 AWS Account ID “611495371442”
AWS 인증 속성 매핑 설정
기본 제공되는 매핑(attribute.aws_role)으로 충분하며, 추가/변경은 필요치 않습니다.•attribute.aws_role 필드 매핑할 AWS Credentials 속성을 설정합니다.
•Grant Access 에서 매핑된 속성을 사용합니다.
서비스 계정 역할 추가
개별 자원 단위로 접근 권한 설정 및 관리가 복잡하기 때문에, 외부 인증된 Workload가 가장할 서비스 계정을 생성하고 권한을 설정합니다.
생성한 서비스 계정에 와 수집을 위한 Viewer 등 역할외 단기 토큰 교환을 위한 Workload Identity User추가합니다.Service account 접근 허용할 AWS 인증 역할 설정
IAM & Admin에 Workloa Identity Federation 메뉴에서 Identity Pool에 생성된 Service account에 대한 Grant Access를 설정 합니다.
Service Account와 접근할 주체 (aws_role) 식별 정보를 입력합니다.CloudXper의 IAM Role ARN : arn:aws:sts::611495371442:assumed-role/CX-PROD-EKS-NODEGROUP-NodeInstanceRole-1HYC11PY1OT07
•설치 구성(1/3) 3번 AWS 인증 속성 매핑 설정에 attribute.aws_role 필드와 값을 입력합니다.
인증 제휴 설정 파일 다운로드
저장 후, 제휴 설정 파일을 다운로드하여, CloudXper 신청서와 함께 생성된 json 파일을 CloudXper 관리자에게 전송합니다.Google SDK에서 인증 토큰 교환 처리에 필요한 AWS 인증 주체 정보와 토큰 교환 방식 등으로 인증 정보 등 민감 정보는 없습니다.
제휴설정 구성확인
Audit Log 확인
Workload Identity Pool 상세 화면에서 Logs View를 클릭하여 Logs Explores에서 identity pool로 요청한 내역을 확인할 수 있습니다.
(Audit Log가 조회되지 않는다면 아래 활성화 부분을 참고)Audit Log를 활성화하기 위해서는 IAM & Admin에서 Audit Logs에 Security Token Service API에 Admin read를 활성화하고,
로그를 조회하는 사용자는 roles/viewer나 roles/logging.viewer 권한이 필요합니다.
gcloud shell script를 통한 WIF 설정
ServiceAccount 생성 script와 연속성이 있는 후속 Step용 gcloud shell script입니다.
=> Service Account의 이름은 앞서 생성한 cxp-collector-sa로 지정하였으며, 만약 이미 별도 ServiceAccount가 생성된 상태면 수정하여 사용 바랍니다.
=> AWS_ROLE_ARN은 CloudXper의 정보로 기입되어있습니다.
* WIF Pool 이름과 Provider 이름, Cred파일명 등의 충돌을 방지하고자 해당 값들이 각 프로젝트 이름 기반으로 생성되지만, 경우에 따라 32글자 제한으로 에러가 발생할 수 있음
shell script를 통해 WIF를 생성하신 후에도, 제휴 설정 파일을 다운로드하여, CloudXper 신청서와 함께 생성된 json 파일을 CloudXper 관리자에게 전송해주시기 바라며,
이후 확인 과정은 GUI 콘솔로 작업하는 것과 동일합니다.
# vi 01_setup_wif_aws.sh 하여 파일 생성
아래의 내용을 스크립트에 넣고 저장
#!/usr/bin/env bash set -euo pipefail # =====================[ USER CONSTANTS – EDIT AS NEEDED ]===================== SA_ID="cxp-collector-sa" # STS-style accepted; will be normalized to IAM Role ARN automatically. AWS_ROLE_ARN="arn:aws:sts::611495371442:assumed-role/CX-PROD-EKS-NODEGROUP-NodeInstanceRole-1HYC11PY1OT07" EMIT_CRED_CONFIG="${EMIT_CRED_CONFIG:-false}" # true|false # You can still override POOL_ID / PROVIDER_ID / CRED_FILE_OUT via ENV if desired. # ============================================================================= # --------------------- utilities --------------------- need() { command -v "$1" >/dev/null 2>&1 || { echo "[ERR] '$1' not found"; exit 1; }; } need gcloud log() { echo "[INFO] $*"; } warn() { echo "[WARN] $*" >&2; } err() { echo "[ERR] $*" >&2; exit 1; } normalize_role_arn() { # Convert STS assumed-role ARN to IAM role ARN if needed local in="$1" if [[ "$in" =~ ^arn:aws:sts::([0-9]{12}):assumed-role/([^/]+)(/.*)?$ ]]; then echo "arn:aws:iam::${BASH_REMATCH[1]}:role/${BASH_REMATCH[2]}" else echo "$in" fi } validate_id() { local id="$1" kind="$2" if [[ ! "$id" =~ ^[a-z0-9-]{4,32}$ ]]; then err "Invalid ${kind} ID: '${id}'. It must be 4-32 chars, [a-z0-9-] only." fi } # --------------------- detect project/account --------------------- ACCOUNT="$(gcloud config get-value account 2>/dev/null || true)" PROJECT_ID="$(gcloud config get-value project 2>/dev/null || true)" [[ -z "${PROJECT_ID}" ]] && err "Run 'gcloud config set project <ID>' first." PROJECT_NUMBER="$(gcloud projects describe "${PROJECT_ID}" --format='value(projectNumber)')" PN6="$(printf "%s" "${PROJECT_NUMBER}" | tail -c 6)" # last 6 digits SA_EMAIL="${SA_ID}@${PROJECT_ID}.iam.gserviceaccount.com" # Short, unique-by-project defaults (safe against 32-char limit) POOL_ID="${POOL_ID:-cxp-wif-${PN6}}" PROVIDER_ID="${PROVIDER_ID:-aws-prov-${PN6}}" CRED_FILE_OUT="${CRED_FILE_OUT:-./wif_cred_config_${PROVIDER_ID}.json}" GCLOUD_QUIET="--quiet" AWS_ROLE_ARN="$(normalize_role_arn "$AWS_ROLE_ARN")" [[ "${AWS_ROLE_ARN}" =~ ^arn:aws:iam::[0-9]{12}:role/.+ ]] || err "Invalid AWS_ROLE_ARN: ${AWS_ROLE_ARN}" AWS_ACCOUNT_ID="$(echo "${AWS_ROLE_ARN}" | sed -E 's#^arn:aws:iam::([0-9]{12}):role/.*#\1#')" # Validate IDs before use validate_id "${POOL_ID}" "WorkloadIdentityPool" validate_id "${PROVIDER_ID}" "WorkloadIdentityPoolProvider" log "Active account : ${ACCOUNT}" log "Project : ${PROJECT_ID} (num=${PROJECT_NUMBER})" log "Service Account: ${SA_EMAIL}" log "WIF Pool/Prov : ${POOL_ID} / ${PROVIDER_ID}" log "AWS Role/Acct : ${AWS_ROLE_ARN} / ${AWS_ACCOUNT_ID}" log "Cred file out : ${CRED_FILE_OUT}" # --------------------- pre-checks --------------------- gcloud iam service-accounts describe "${SA_EMAIL}" --project="${PROJECT_ID}" >/dev/null 2>&1 \ || err "Service Account not found: ${SA_EMAIL} (create it first)." # --------------------- enable required APIs --------------------- log "Enabling APIs (iam, iamcredentials, sts)" gcloud ${GCLOUD_QUIET} services enable \ iam.googleapis.com \ iamcredentials.googleapis.com \ sts.googleapis.com \ --project="${PROJECT_ID}" >/dev/null # --------------------- pool helpers --------------------- pool_state() { gcloud iam workload-identity-pools describe "${POOL_ID}" \ --project="${PROJECT_ID}" --location=global \ --format='value(state)' 2>/dev/null || echo "MISSING" } wait_for_pool_active() { local timeout="${1:-180}" waited=0 while true; do local st; st="$(pool_state)" case "${st}" in ACTIVE) log "Pool state=ACTIVE"; return 0;; CREATING|UPDATING) warn "Pool state=${st}; waiting...";; DELETING|DELETED) err "Pool state=${st}. Use a NEW POOL_ID or manually undelete, then rerun.";; MISSING) warn "Pool not visible yet; waiting...";; *) warn "Pool state=${st}; waiting...";; esac sleep 4; waited=$((waited+4)) (( waited >= timeout )) && err "Pool did not become ACTIVE within ${timeout}s" done } # --------------------- ensure pool --------------------- if gcloud iam workload-identity-pools describe "${POOL_ID}" \ --project="${PROJECT_ID}" --location=global >/dev/null 2>&1; then log "Pool exists: ${POOL_ID}" else log "Creating Pool: ${POOL_ID}" gcloud ${GCLOUD_QUIET} iam workload-identity-pools create "${POOL_ID}" \ --project="${PROJECT_ID}" \ --location="global" \ --display-name="CloudXper WIF Pool" \ --description="AWS↔GCP federation for CloudXper" fi wait_for_pool_active 240 # --------------------- ensure provider --------------------- provider_state() { gcloud iam workload-identity-pools providers describe "${PROVIDER_ID}" \ --project="${PROJECT_ID}" --location=global \ --workload-identity-pool="${POOL_ID}" --format='value(state)' 2>/dev/null || echo "MISSING" } provider_exists() { [[ "$(provider_state)" != "MISSING" ]]; } if provider_exists; then local pst; pst="$(provider_state)" log "Provider exists: ${PROVIDER_ID} (state=${pst})" if [[ "${pst}" == "DELETED" || "${pst}" == "DELETING" ]]; then err "Provider state=${pst}. Use a NEW PROVIDER_ID or manually undelete, then rerun." fi else log "Creating AWS Provider: ${PROVIDER_ID}" tries=0; max=6 while (( tries < max )); do if gcloud ${GCLOUD_QUIET} iam workload-identity-pools providers create-aws "${PROVIDER_ID}" \ --project="${PROJECT_ID}" \ --location="global" \ --workload-identity-pool="${POOL_ID}" \ --account-id="${AWS_ACCOUNT_ID}"; then log "Provider created: ${PROVIDER_ID}" break else rc=$? warn "Provider creation failed (rc=${rc}). Pool state=$(pool_state). Retrying..." sleep $((2 ** tries)) # 1,2,4,8,16,32s tries=$((tries+1)) fi done provider_exists || err "Failed to create provider after ${max} attempts." fi # --------------------- bind WorkloadIdentityUser to SA --------------------- MEMBER="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${POOL_ID}/attribute.aws_role/${AWS_ROLE_ARN}" if gcloud iam service-accounts get-iam-policy "${SA_EMAIL}" --project="${PROJECT_ID}" --format=json | grep -q "${MEMBER}"; then log "WIF binding already present (roles/iam.workloadIdentityUser)." else log "Adding WIF binding → ${SA_EMAIL}" gcloud ${GCLOUD_QUIET} iam service-accounts add-iam-policy-binding "${SA_EMAIL}" \ --project="${PROJECT_ID}" \ --member="${MEMBER}" \ --role="roles/iam.workloadIdentityUser" >/dev/null fi # --------------------- optional: cred config file --------------------- if [[ "${EMIT_CRED_CONFIG}" == "true" ]]; then log "Creating cred config: ${CRED_FILE_OUT}" gcloud ${GCLOUD_QUIET} iam workload-identity-pools create-cred-config \ "projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${POOL_ID}/providers/${PROVIDER_ID}" \ --project="${PROJECT_ID}" \ --service-account="${SA_EMAIL}" \ --output-file="${CRED_FILE_OUT}" \ --aws echo "[OK] Cred config created at ${CRED_FILE_OUT}" else log "Cred config generation skipped (set EMIT_CRED_CONFIG=true to enable)." fi echo "[DONE] WIF setup completed."# bash 01_setup_wif_aws.sh 수행
Step3. CSR 자동화 권한 설정(선택사항)
New ITSM의 CSR자동화를 위해서는 서비스/자원 변경에 필요한 권한을 설정해야 합니다.
Step3.1. CSR자동화 Role 생성
IAM & Admin 화면에서 권한 설정을 위한 Role을 생성합니다.
Step3.2. Role의 Permissions 설정
①ID는 Role식별자로 숫자,영문,_, . 만 가능합니다.
②Role launch stage는 정책 적용을 위한 Lifecycle로 General Availability를 선택합니다. 참고로, Lifecycle은 Alpha > Beta > General Availability > Disabled가 있습니다.
③“ADD PERMISSIONS” 버튼을 클릭하여 필요한 Action 권한을 추가합니다.
④ Add Permissions 팝업창에서 Filter에 추가할 Permission을 검색하여 체크한 후 “ADD”버튼을 클릭합니다.
참고로 GCP의 predefined role을 알고 있는 경우에는 상단에 “Filter permissions by role”에서 predefined role의 permissio을 확인하고 추가할 수도 있습니다.
CSR 자동화를 위해 필요한 Permissions은 34개로 다음과 같습니다.
AutoCSR Permission List
compute.disks.create
compute.disks.delete
compute.disks.setLabels
compute.disks.use
compute.disks.useReadOnly
compute.firewalls.create
compute.firewalls.get
compute.firewalls.update
compute.globalOperations.get
compute.images.useReadOnly
compute.instances.attachDisk
compute.instances.delete
compute.instances.get
compute.instances.setDeletionProtection
compute.instances.start
compute.instances.startWithEncryptionKey
compute.instances.stop
compute.networks.updatePolicy
compute.snapshots.useReadOnly
compute.zoneOperations.get
iam.roles.create
iam.roles.get
iam.roles.list
iam.roles.update
resourcemanager.projects.get
resourcemanager.projects.getIamPolicy
resourcemanager.projects.setIamPolicy
serviceusage.services.use
storage.buckets.create
storage.buckets.delete
storage.buckets.get
storage.buckets.update
storage.objects.delete
storage.objects.list
Step3.3. Role부여
CloudXper 응용에서 사용 중인 Service Account계정에 Role을 부여합니다.
Service Account를 새로이 생성하려 한다면 Step2 과정을 참조하십시요.
⑤ 해당 Service Account 계정의 우측 Edit member버튼을 클릭합니다.
우측 팝업이 열리면서 앞에서 생성한 Custom Role을 설정할 수 있습니다.
⑥ Role 목록에서 앞에서 생성한 Custom Role을 추가하고 저장합니다.
gcloud shell script를 통한 AutoCSR Role 생성 (선택사항)
ServiceAccount 생성 script와 WIF 설정 스크립트와 연속성이 있는 후속 Step용 gcloud shell script입니다.
선택사항 스크립트로써 이 스크립트를 수행하지 않아도 후속 스크립트인 API 활성화 스크립트는 동작합니다.
=> Service Account의 이름을 cxp-collector-sa로 지정하여 작업한 스크립트임
=> Role ID의 이름은 콘솔 가이드와 동일하게 cxpCsrAutomation으로 지정하여 작업한 스크립트임
# vi 02_setup_csr_role.sh 하여 파일 생성
아래의 내용을 스크립트에 넣고 저장
#!/usr/bin/env bash set -euo pipefail # =====================[ USER CONSTANTS – EDIT AS NEEDED ]===================== # The Service Account that should receive the custom role. SA_ID="${SA_ID:-cxp-collector-sa}" # Custom Role ID at the project level (allowed: letters/digits/._ ; 3–64 chars). CSR_ROLE_ID="${CSR_ROLE_ID:-cxpCsrAutomation}" CSR_ROLE_TITLE="${CSR_ROLE_TITLE:-CloudXper CSR Automation}" CSR_ROLE_DESC="${CSR_ROLE_DESC:-Permissions for CSR automation (CloudXper guide Step3)}" # ============================================================================= need() { command -v "$1" >/dev/null 2>&1 || { echo "[ERR] '$1' not found"; exit 1; }; } need gcloud log() { echo "[INFO] $*"; } err() { echo "[ERR] $*" >&2; exit 1; } PROJECT_ID="$(gcloud config get-value project 2>/dev/null || true)" [[ -z "${PROJECT_ID}" ]] && err "Run 'gcloud config set project <ID>' first." SA_EMAIL="${SA_ID}@${PROJECT_ID}.iam.gserviceaccount.com" # Permissions from the guide (Step3.2 “csr permission list”). # Source: guide page Step3.2 permissions list. :contentReference[oaicite:1]{index=1} PERMS_CSV="$(cat <<'CSV' compute.disks.create,compute.disks.setLabels,compute.disks.delete,compute.disks.use,compute.disks.useReadOnly,compute.firewalls.create,compute.firewalls.get,compute.firewalls.update,compute.globalOperations.get,compute.images.useReadOnly,compute.instances.attachDisk,compute.instances.delete,compute.instances.setDeletionProtection,compute.instances.get,compute.instances.start,compute.instances.startWithEncryptionKey,compute.instances.stop,compute.networks.updatePolicy,compute.snapshots.useReadOnly,compute.zoneOperations.get,iam.roles.create,iam.roles.get,iam.roles.list,iam.roles.update,resourcemanager.projects.get,resourcemanager.projects.getIamPolicy,resourcemanager.projects.setIamPolicy,serviceusage.services.use,storage.buckets.create,storage.buckets.delete,storage.buckets.get,storage.buckets.update,storage.objects.delete,storage.objects.list CSV )" log "Project: ${PROJECT_ID}" log "Service Account: ${SA_EMAIL}" log "Custom Role ID: ${CSR_ROLE_ID}" # Ensure SA exists gcloud iam service-accounts describe "${SA_EMAIL}" --project="${PROJECT_ID}" >/dev/null 2>&1 \ || err "Service Account not found: ${SA_EMAIL}" # Create role if not exists; otherwise update (add missing permissions) & set stage=GA. if gcloud iam roles describe "${CSR_ROLE_ID}" --project="${PROJECT_ID}" >/dev/null 2>&1; then log "Custom role exists; updating to stage=GA and ensuring required permissions." gcloud iam roles update "${CSR_ROLE_ID}" \ --project="${PROJECT_ID}" \ --stage="GA" \ --add-permissions="${PERMS_CSV}" \ --quiet else log "Creating custom role: ${CSR_ROLE_ID}" gcloud iam roles create "${CSR_ROLE_ID}" \ --project="${PROJECT_ID}" \ --title="${CSR_ROLE_TITLE}" \ --description="${CSR_ROLE_DESC}" \ --stage="GA" \ --permissions="${PERMS_CSV}" \ --quiet fi # Grant the custom role to the SA at the project level (Step3.3). CUSTOM_ROLE_FULL="projects/${PROJECT_ID}/roles/${CSR_ROLE_ID}" log "Granting custom role to SA: ${CUSTOM_ROLE_FULL} → ${SA_EMAIL}" gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:${SA_EMAIL}" \ --role="${CUSTOM_ROLE_FULL}" \ --quiet echo "[DONE] CSR role ready and granted: ${CUSTOM_ROLE_FULL} → ${SA_EMAIL}"# bash 02_setup_csr_role.sh 수행
Step4. GCP API 활성화
API Library로 이동하여 수집할 서비스의 API가 활성화되어있는 지 확인합니다.
활성화되어있지 않다면 활성화되어야, 수집이 정상적으로 이뤄집니다.
수집 대상 서비스목록입니다. 검색창에 서비스를 검색하시고, API를 활성화하시기 바랍니다.
WIF 인증 방식의 경우 Impersonated Service Account로 API 요청을 보내게 되며, 해당 프로젝트는 Quota 프로젝트로 API 활성화와 Quota가 관리됩니다.
만일, 별도 프로젝트 (Quota Project)에 Impersonated Service Account로 다른 프로젝트의 자원을 수집하는 구성인 경우, 반드시 양측 모두 API가 활성화되어야 합니다.
운영 관리자는 수집에 사용된 Impersonated Service Account와 API 활성화가 필요한 URL을 확인 점검하고 있으나,
해당 오류 내용에서 project id만 확인 할 수 있기 때문에 상기 내용을 전달드리면, 두군데 프로젝트의 API 활성화 여부를 점검부탁드립니다.
Compute Engine API : instance, disk, vpc, firewall, load balancer 등
Cloud DNS API : zone, record set
Cloud SQL Admin API : sql instance
Cloud Storage : buckets
Cloud Resource Manager API : iam
Kubernetes Engine API: cluster, node pool
* k8s 내 deployment, pod 등 자원은 k8s client로 수집하며, 네트워크 접근이 허용되어야 합니다.Recommender API: recommender
API Library 페이지로 이동합니다.
서비스목록의 API를 활성화 합니다. (아래는 Cloud Resource Manager API 화면 예시입니다)
Recommender API를 활성화 합니다.
gcloud shell script를 통한 GCP API 활성화
앞서 제시된 스크립트의 후속 Step용 gcloud shell script이나 특별한 패러미터 지정 등이 없으므로, 단독 생성 및 수행도 가능합니다.
=> WIF 관련 API(iam/iamcredentials/sts)는 Step 2에서 자동 활성화됩니다.
# vi 03_enable_apis.sh 하여 파일 생성
아래의 내용을 스크립트에 넣고 저장
#!/usr/bin/env bash set -euo pipefail need() { command -v "$1" >/dev/null 2>&1 || { echo "[ERR] '$1' not found"; exit 1; }; } need gcloud log() { echo "[INFO] $*"; } err() { echo "[ERR] $*" >&2; exit 1; } PROJECT_ID="$(gcloud config get-value project 2>/dev/null || true)" [[ -z "${PROJECT_ID}" ]] && err "Run 'gcloud config set project <ID>' first." # API list from the guide Step4. # (Compute, Cloud DNS, Cloud SQL Admin, Cloud Storage, Cloud Resource Manager, GKE, Recommender) # Source: guide page Step4. :contentReference[oaicite:3]{index=3} APIS=( compute.googleapis.com dns.googleapis.com sqladmin.googleapis.com storage.googleapis.com cloudresourcemanager.googleapis.com container.googleapis.com recommender.googleapis.com ) log "Project: ${PROJECT_ID}" log "Enabling ${#APIS[@]} APIs required by the guide (Step4)..." gcloud services enable "${APIS[@]}" --project="${PROJECT_ID}" --quiet echo "[DONE] APIs enabled."# bash 03_enable_apis.sh 수행
Step5. 비용 설정
추후 업데이트 예정
Step6. CUD 조회를 위한 가이드