문제 해결

이 페이지에서는 VPC 서비스 제어를 구성할 때 발생할 수 있는 여러 문제들을 보여줍니다.

VPC 서비스 제어 오류 찾기

이 섹션에서는 다음과 같은 감사 로그에서 VPC 오류를 찾는 방법을 자세히 설명합니다.

오류의 고유 ID 사용

VPC 서비스 제어에서 생성된 오류에는 관련 감사 로그를 식별하는 데 사용되는 고유 ID가 포함됩니다.

이 절차에서는 Logging 문서의 용어를 사용합니다. 자세한 내용은 기본 로그 필터를 참조하세요.

고유 ID를 사용하여 오류에 대한 정보를 가져오려면 다음 안내를 따르세요.

  1. Cloud Console에서 오류를 트리거한 서비스 경계 내 프로젝트의 Stackdriver Logging 페이지로 이동합니다.

    Stackdriver Logging 페이지로 이동

  2. 검색 필터 상자에 오류의 고유 ID를 입력합니다.

메타데이터를 사용하여 로그 필터링

VPC 서비스 제어와 관련된 오류를 찾으려면 Cloud Logging을 사용합니다.

Console

이 절차에서는 Logging 문서의 용어를 사용합니다. 자세한 내용은 기본 로그 필터를 참조하세요.

Logging에서 지난 24시간 동안의 VPC 서비스 제어 오류를 확인하려면 다음 안내를 따르세요.

  1. Google Cloud Console에서 서비스 경계 내 프로젝트의 Stackdriver Logging 페이지로 이동합니다.

    Stackdriver Logging 페이지로 이동

  2. 검색 필터 상자에 다음을 입력합니다.

    protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
    
  3. 리소스 기본 선택기 메뉴에서 감사를 받은 리소스를 선택합니다.

  4. 시간 범위 선택기 드롭다운 메뉴에서 지난 24시간을 선택합니다.

  5. 선택사항: 서로 다른 기간 중에 발생한 VPC 서비스 제어 오류를 찾으려면 시간 범위 선택기 드롭다운 메뉴를 사용합니다.

gcloud

  • 지난 24시간 동안의 VPC 서비스 제어 오류를 확인하려면 다음 명령어를 사용하세요.

    gcloud logging read 'protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"'
    

    기본적으로 read 명령어는 지난 24시간으로 제한됩니다. 서로 다른 기간의 VPC 서비스 제어 로그를 가져오려면 다음 명령어 중 하나를 사용합니다.

  • 현재 날짜를 기준으로 로그를 제한하려면 다음을 사용하세요.

    gcloud logging read \
    'protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"' \
      --freshness=DURATION
    

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

    • DURATION은 형식이 지정된 기간입니다. 형식 지정에 대한 자세한 내용은 gcloud상대적 기간/시간 형식을 참조하세요.

    예를 들어 지난주 동안 발생한 모든 VPC 서비스 제어 오류를 확인하려면 다음을 사용하세요.

    gcloud logging read \
    'protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"' \
      --freshness=7d
    
  • 로그를 특정 시간 프레임으로 제한하려면 다음을 사용하세요.

    gcloud logging read \
    'protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata" AND
      timestamp>="START_DATETIME" AND
      timestamp<="END_DATETIME"'
    

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

    • START_DATETIMEEND_DATETIME 형식은 날짜/시간 문자열로 지정됩니다. 형식 지정에 대한 자세한 내용은 gcloud절대적 날짜/시간 형식을 참조하세요.

    예를 들어 2019년 3월 22일부터 2019년 3월 26일까지 발생한 모든 VPC 서비스 제어 오류를 확인하려면 다음을 사용하세요.

    gcloud logging read \
    'protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata" AND
      timestamp>="2019-03-22T23:59:59Z" AND
      timestamp<="2019-03-26T00:00:00Z"'
    

미지원 서비스

VPC 서비스 제어가 지원하는 제품 및 서비스에 대한 자세한 내용은 지원되는 제품 페이지를 참조하세요.

gcloud 명령줄 도구 또는 Access Context Manager API를 사용하여 미지원 서비스를 제한하려는 경우 오류가 발생합니다.

지원되는 서비스 데이터에 대한 프로젝트 간 액세스는 VPC 서비스 제어에서 차단합니다. 또한 제한된 VIP는 미지원 서비스를 호출하는 워크로드의 기능을 차단하는 데 사용할 수 있습니다.

공유 VPC

공유 VPC를 사용할 경우 공유 VPC 네트워크에 속하는 프로젝트가 포함된 서비스 경계에는 네트워크를 호스팅하는 프로젝트도 포함되어야 합니다. 공유 VPC 네트워크에 속하는 프로젝트가 호스트 프로젝트와 같은 경계에 있지 않으면 서비스가 예상대로 작동하지 않거나 완전히 차단될 수 있습니다.

공유 VPC 네트워크 호스트가 네트워크에 연결된 프로젝트와 동일한 서비스 경계에 있는지 확인합니다.

경계 간 요청

일반적으로 액세스 수준을 사용하여 경계 에서 보호되는 리소스의 서비스 경계 외부에서 요청을 허용할 수 있습니다.

하지만 일반적으로 액세스 수준에서 요청을 허용하더라도 다른 경계에서 보호되는 리소스의 경계에 있는 프로젝트에서의 요청은 거부됩니다.

예를 들어 경계 1의 프로젝트 A가 프로젝트 B에서 리소스를 요청한다고 가정해보겠습니다. 프로젝트 B의 리소스는 경계 2로 보호됩니다. 프로젝트 A는 경계에 있으므로 일반적으로 경계 2의 액세스 수준에서 보호되는 리소스의 요청을 허용하더라도 요청은 거부됩니다.

경계 간 요청을 용이하게 하는 두 가지 방법은 다음과 같습니다.

  • 경계 브리지를 사용합니다. 브릿지를 사용하면 서로 다른 경계에 있는 프로젝트 두 개 이상에서 프로젝트의 모든 서비스에 요청할 수 있습니다. 이러한 요청은 서비스가 경계로 보호되는 경우에도 허용됩니다.

  • 요청 서비스와 대상 리소스 모두 경계로 보호되지 않는지 확인합니다. 이 시나리오에서는 보호되는 서비스가 없으므로 작업이 성공합니다.

VPC 서비스 제어로 인한 오류인지 확인

VPC 서비스 제어는 Google Cloud의 속성을 수정하며, 사용자가 무엇을 조사해야 하는지 잘 모를 경우 디버깅하기 어려운 서비스간의 연쇄 효과를 일으킬 수 있습니다.

VPC 서비스 제어와 관련된 오류인지 파악하려면 VPC 서비스 제어를 사용 설정한 후 사용하려는 프로젝트 및 서비스에 적용했는지 확인하세요. gcloud 명령줄 도구나 Cloud Console을 통해 프로젝트와 서비스가 VPC 서비스 제어로 보호되는지 여부를 확인할 수 있습니다.

서비스 경계 안에 있는 프로젝트에서 VPC 서비스 제어에 의해 제한된 서비스로 표시된 서비스를 간접적으로 사용한다고 고려해보세요. 이러한 경우 VPC 서비스 제어가 잘못될 수 있습니다.

알려진 문제점에 대한 자세한 내용은 알려진 서비스 제한사항을 참조하세요.

일반적으로 서비스는 종속 항목의 오류 메시지를 전파합니다. 다음 오류 중 하나가 발생하면 VPC 서비스 제어에 문제가 있다는 의미입니다.

  • Cloud Storage: 403: Request violates VPC Service Controls.

  • BigQuery: 403: VPC Service Controls: Request is prohibited by organization's policy.

  • 기타 서비스: 403: Request is prohibited by organization's policy.

VPC 서비스 제어가 예기치 않은 이유로 차단한 요청 디버깅

VPC 서비스 제어 감사 로그는 VPC 서비스 제어에서 차단한 요청을 디버깅할 수 있는 기본 도구입니다.

예기치 않게 액세스가 차단되었으면 요청 소스인 프로젝트의 감사 로그를 참조하면 됩니다. 이러한 로그에는 요청된 리소스에 대한 중요한 데이터와 요청이 거부된 이유가 나와 있습니다.

로그를 보는 방법은 로그 보기를 참조하세요.

다음 표에는 VPC 서비스 제어를 사용할 때 발생할 수 있는 violationReason 값이 나와 있습니다.

violationReason 설명
RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER 감사 로그 레코드의 resourceNames 아래에 나열된 리소스가 동일한 서비스 경계에 없습니다.
NETWORK_NOT_IN_SAME_SERVICE_PERIMETER 감사 로그 레코드에서 callerNetworkresourceNames에 해당하는 리소스가 동일한 서비스 경계에 없습니다.
NO_MATCHING_ACCESS_LEVEL

감사 로그 레코드의 callerIp에 해당하는 IP 주소가 서비스 경계에 할당된 액세스 수준의 IP 범위와 일치하지 않습니다.

SERVICE_NOT_ALLOWED_FROM_VPC 호출되는 서비스는 서비스 경계의 VPC 액세스 가능 서비스 구성에서 허용되지 않습니다.

인그레스 및 이그레스 규칙 위반

감사 로그에는 경계 위반을 이해하는 데 도움이 되는 인그레스 및 이그레스 규칙 위반에 대한 정보가 포함되어 있습니다.

인그레스 규칙 위반

인그레스 규칙 위반은 경계 외부의 API 클라이언트가 경계 내부 리소스에 액세스하려고 했음을 나타냅니다. 일치하는 인그레스 규칙이나 액세스 수준이 없으므로 서비스 경계가 요청을 거부합니다.

감사 로그의 인그레스 규칙 위반에는 다음 세부정보가 포함됩니다.

  • 인그레스 규칙 위반이 발생한 경계의 이름입니다.
  • 경계 외부의 API 클라이언트가 액세스하려고 한 경계 내부의 리소스입니다.

다음 인그레스 규칙 위반 예시에서 경계 외부의 API 클라이언트가 경계 prod-perimeter 내부의 Cloud Storage 버킷 prod-protected-storage-bucket에 액세스하려고 합니다.

ingressViolations: [
  0: {
    targetResource: "projects/1234/buckets/prod-protected-storage-bucket"
    servicePerimeter: "accessPolicies/123456789/servicePerimeters/prod-perimeter"
  }
]

이그레스 규칙 위반

감사 로그에서 이그레스 규칙 위반은 다음 이벤트 중 하나를 나타냅니다.

  • 경계 내부의 API 클라이언트가 경계 외부의 리소스에 액세스하려고 했습니다.
  • 경계 내부의 리소스와 경계 외부의 리소스를 포함하는 API 요청입니다. 예를 들어 한 버킷이 경계 내부에 있고 다른 버킷이 경계 외부에 있는 복사 명령어를 호출하는 Cloud Storage 클라이언트입니다.

서비스 경계는 일치하는 이그레스 규칙이 없기 때문에 요청을 거부합니다. 감사 로그의 이그레스 규칙 위반에는 다음 세부정보가 포함됩니다.

  • 소스 유형(예: 네트워크나 리소스)
  • 경계에서 이그레스 위반이 발생한 리소스나 네트워크인 소스
  • 이그레스 위반이 발생한 경계
  • 요청에서 액세스하려고 한 경계 외부의 대상 리소스

다음 이그레스 규칙 위반 예시에서 API 요청에는 경계 prod-perimeter 내에 있는 projects/5678의 리소스와 경계 외부에 있는 Cloud Storage 버킷 external-storage-bucket의 객체가 포함됩니다.

egressViolations: [
  0: {
    sourceType: "Resource"
    source: "projects/5678"
    targetResource: "projects/4321/buckets/external-storage-bucket/objects/corp-resources.json"
    servicePerimeter: "accessPolicies/123456789/servicePerimeters/prod-perimeter"
  }
]

시나리오 예시

다음 예시에서는 VPC 서비스 제어를 사용하는 동안 발생할 수 있는 문제를 설명합니다.

온프레미스에서 Cloud Storage 액세스

이 예시에서 VPC 서비스 제어는 직원 워크스테이션(callerIp로 식별됨)에서 프로젝트 corp-storage의 Cloud Storage 버킷으로 전송되는 요청을 차단합니다.

이 요청은 다음과 같은 감사 로그 레코드를 생성합니다.

{
 insertId:  "222lvajc6f7"
 logName:  "projects/corp-storage/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "someone@google.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/_"
   ]
   violationReason:  "NO_MATCHING_ACCESS_LEVEL"
  }
  methodName:  "google.storage.NoBillingOk"
  requestMetadata: {
   callerIp:  "b1d5:d26d:5b17:43fe:d358:586b:db59:9617"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/690885588241"
  serviceName:  "storage.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-27T21:40:43.823209571Z"
 resource: {
  labels: {
   method:  "google.storage.NoBillingOk"
   project_id:  "corp-storage"
   service:  "storage.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-27T21:40:42.973784140Z"
}

corp-storage 프로젝트는 서비스 경계에 포함되어 있습니다. 직원 워크스테이션은 해당 경계 내에 있는 네트워크에 있지 않습니다. 직원 워크스테이션이 경계 외부에 존재하므로 요청이 차단됩니다.

프로젝트 외부의 VM에서 BigQuery 액세스

이 예시에서 458854174376 프로젝트(data-collector)에 속한 VM이 798816221974 프로젝트(corp-resources-protected)의 데이터 세트에서 BigQuery 쿼리를 실행하려 했지만 거부되었습니다.

VM은 다음 쿼리를 사용합니다.

bq --project=corp-resources-protected query 'select count(*) from babynames.yob2000'

이 쿼리는 다음과 같은 출력을 반환합니다.

BigQuery error in query operation: VPC Service Controls: Request is
prohibited by organization's policy. Operation ID:
33643962-6a0f-4091-9283-bcdf7e9271f0

다음 감사 로그 레코드가 생성됩니다.

{
 insertId:  "1ei551d2pdq"
 logName:  "projects/corp-resources-protected/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "714877721106-compute@example.gserviceaccount.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/1004338142803"
   ]
   violationReason:  "NETWORK_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "bigquery.googleapis.com/bigquery.jobs.create"
  requestMetadata: {
   callerIp:  "10.105.0.2"
   callerNetwork:  "//compute.googleapis.com/projects/ameet-dataflow/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/1004338142803"
  serviceName:  "bigquery.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-28T23:06:13.579882505Z"
 resource: {
  labels: {
   method:  "bigquery.googleapis.com/bigquery.jobs.create"
   project_id:  "corp-resources-protected"
   service:  "bigquery.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-28T23:06:12.799656975Z"
}

이 예시에서 violationReasonNETWORK_NOT_IN_SAME_SERVICE_PERIMETER입니다. callerNetworkcallerIp 다음에 추가됩니다. IP 주소는 비공개이며 정확한 네트워크 정보도 제공되었습니다. 문제와 관련된 리소스는 VpcServiceControlAuditMetadata.resourceNamesrequestMetadata.callerNetwork(네트워크를 소유한 프로젝트) 등 두 곳에 나와 있습니다.

문제는 corp-resources-protected 프로젝트는 서비스 경계 내부에 있지만 VM이 속한 네트워크가 포함된 프로젝트인 data-collector는 서비스 경계 외부에 있다는 점입니다. 이 경우 액세스가 예상대로 거부됩니다.

프로젝트 간 BigQuery 쿼리

이 예시에서 perimeter-network 프로젝트에 속한 VM은 perimeter-network와 동일한 서비스 경계에 있는 corp-resources-protected 프로젝트와 그렇지 않은 corp-resources-public 프로젝트 등 두 프로젝트의 BigQuery 인스턴스를 쿼리하려 합니다.

VM은 다음 명령어를 사용합니다.

bq query --use_legacy_sql=false \
  'select count(priv.name),count(pub.name) from \
  `corp-resources-protected.babynames.yob2000` as priv, \
  `corp-resources-public.babynames.yob2000` as pub'

이 쿼리는 다음과 같은 출력을 반환합니다.

BigQuery error in query operation: Error processing job
'example:bqjob_r211e6f6eec928ffb_000001675c996aa8_1': VPC Service Controls:
Request is prohibited by organization's policy. Operation ID:
dc4fc177-4850-4fc5-b2e7-8c33f302149a

다음 감사 로그 레코드가 생성됩니다.

{
 insertId:  "17kg4exd24ag"
 logName:  "projects/perimeter-network/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/117961063178"
    1:  "projects/690885588241"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "bigquery.googleapis.com/bigquery.tables.getData"
  requestMetadata: {
   callerIp:  "130.211.225.66"
   callerNetwork:  "//compute.googleapis.com/projects/perimeter-network/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/927005422713"
  serviceName:  "bigquery.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-28T20:48:51.384237810Z"
 resource: {
  labels: {
   method:  "bigquery.googleapis.com/bigquery.tables.getData"
   project_id:  "perimeter-network"
   service:  "bigquery.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-28T20:48:50.561884949Z"
}

callerNetworkVpcServiceControlAuditMetadata.resourceNames를 확인하면 perimeter-network, 117961063178(corp-resources-public), 690885588241(corp-resources-protected) 등 프로젝트 세 개를 확인할 수 있습니다. corp-resources-publicperimeter-networkcorp-resources-protected와 같은 서비스 경계에 없다는 점을 기억하세요.

violationReason, RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER는 요청의 일부 리소스가 요청에 적용되는 경계 외부에 있다는 의미입니다. 이 경우 리소스는 corp-resources-public입니다.

경계 내로 Cloud Storage 파일 이동

이 예시에서 perimeter-network 프로젝트의 VM은 명령어를 사용하여 corp-resources-protected 프로젝트에 있는 한 Cloud Storage 버킷에서 corp-resources-public 프로젝트에 있는 다른 버킷으로 파일을 이동합니다.

VM은 다음 명령어를 사용합니다.

gsutil mv gs://corp-resources-private-1/yob2000.txt gs://corp-resources-public-1/babynames/

이 명령어는 다음 출력을 반환합니다.

Copying gs://corp-resources-private-1/yob2000.txt [Content-Type=text/plain]...
AccessDeniedException: 403 Request violates VPC Service Controls.

다음 감사 로그 레코드가 생성됩니다.

{
 insertId:  "1xxnssmd2hqo"
 logName:  "projects/perimeter-network/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "storage-accessing@example.iam.gserviceaccount.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/_/buckets/corp-resources-public-1"
   ]
   violationReason:  "NETWORK_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "google.storage.BillingRequiredRead"
  requestMetadata: {
   callerIp:  "130.211.225.66"
   callerNetwork:  "//compute.googleapis.com/projects/perimeter-network/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/927005422713"
  serviceName:  "storage.googleapis.com"
  status: {…}
 }
 receiveTimestamp:  "2018-11-28T00:45:31.531623485Z"
 resource: {
  labels: {
   method:  "google.storage.BillingRequiredRead"
   project_id:  "perimeter-network"
   service:  "storage.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-28T00:45:31.351140381Z"
}

이 경우 나열된 메서드가 BillingRequiredRead이고 수행된 작업이 move이므로 로그가 다소 모호합니다. 이는 VPC 서비스 제어의 현재 감사 로그 기능에 적용되는 제한사항입니다.

이유는 다소 모호하지만 이 감사 로그 레코드는 요청의 일부 리소스가 요청에 적용되는 경계 외부에 있음을 나타냅니다. 이 경우 리소스는 corp-resources-public입니다.

경계 외부로 Cloud Storage 파일 이동

이 예시에서 public-network 프로젝트의 VM은 명령어를 사용하여 corp-resources-protected 프로젝트에 있는 한 Cloud Storage 버킷에서 corp-resources-public 프로젝트에 있는 다른 버킷으로 파일을 이동합니다.

corp-resources-protected는 서비스 경계로 보호됩니다. public-networkcorp-resources-public은 경계 외부에 있습니다.

VM은 다음 명령어를 사용합니다.

gsutil mv gs://corp-resources-private-1/yob2000.txt gs://corp-resources-public-1/babynames/

이 명령어는 다음 출력을 반환합니다.

Copying gs://corp-resources-private-1/yob2000.txt [Content-Type=text/plain]...
AccessDeniedException: 403 Request violates VPC Service Controls.

다음 감사 로그 레코드가 생성됩니다.

{
 insertId:  "10moqhsch9v"
 logName:  "projects/corp-resources-private/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "user@example.biz"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/_/buckets/corp-resources-private-1/objects/yob2000.txt"
    1:  "projects/_/buckets/corp-resources-public-1/objects/out.txt"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "google.storage.Write"
  requestMetadata: {
   callerIp:  "2620:15c:2c4:203:63d6:5eb8:418d:c034"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/1004338142803"
  serviceName:  "storage.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-30T16:34:46.948010626Z"
 resource: {
  labels: {
   method:  "google.storage.Write"
   project_id:  "corp-resources-private"
   service:  "storage.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-30T16:34:46.898098978Z"
}

이 예시에서 감사 로그는 서비스 경계 범위 외부로 데이터를 복사할 수 없음을 나타냅니다(두 리소스 모두 감사 로그 레코드에 있음). 요청이 경계 외부(public-network에 있는 VM)에서 발생하고 버킷 중 하나가 경계(corp-resources-public-1) 외부에 있다는 점을 기억하세요.

경계 외부의 VM은 corp-resources-public-1 버킷에 데이터를 쓸 수 있으므로 이전 예시에서 실패한 검사가 성공합니다. 그러나 실제로 데이터를 복사하는 후속 검사는 실패합니다.

이 예시에서는 단일 사용자 작업으로 인해 VPC 서비스 제어 적용을 통과해야 하는 내부 작업이 여러 번 발생하는 경우를 보여줍니다.

경계 내부의 VM에서 BigQuery 데이터 세트 사본

이 예시에서 927005422713 프로젝트(perimeter-network)의 VM은 BigQuery 데이터 세트를 corp-resources-private 프로젝트에서 corp-resources-public 프로젝트(117961063178)로 복사하려 합니다. perimeter-networkcorp-resources-private는 경계를 공유하지만 corp-resources-public은 경계 외부에 있습니다.

VM은 다음 명령어를 사용합니다.

bq cp corp-resources-private:babynames.yob2000 \
  corp-resources-public:babynames.yob2000

이 명령어는 다음 출력을 반환합니다.

BigQuery error in cp operation: VPC Service Controls: Request is prohibited by
organization's policy. Operation ID: c00dbc44-460f-4bd0-9d09-cda98ac800f9

다음 감사 로그 레코드가 생성됩니다.

{
 insertId:  "146o5fd2hbp"
 logName:  "projects/perimeter-network/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/117961063178"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "bigquery.googleapis.com/bigquery.tables.get"
  requestMetadata: {
   callerIp:  "131.201.221.16"
   callerNetwork:  "//compute.googleapis.com/projects/perimeter-network/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/927005422713"
  serviceName:  "bigquery.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-28T00:27:05.688803777Z"
 resource: {
  labels: {
   method:  "bigquery.googleapis.com/bigquery.tables.get"
   project_id:  "perimeter-network"
   service:  "bigquery.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-28T00:27:05.378584819Z"
}

이 예시에는 로깅 메커니즘의 제한사항과 BigQuery의 분산 아키텍처로 인해 이 요청과 관련된 모든 리소스를 보여주는 단일 기본 API 작업이 없습니다.

감사 로그 레코드는 데이터를 복사하기 위해 BigQuery가 perimeter-network 프로젝트(요청 소스)의 네트워크를 사용하여 대상 프로젝트(corp-resources-public)에 액세스해야 하므로 작업이 실패했음을 나타냅니다. corp-resources-publicperimeter-network를 보호하는 경계 외부에 있다는 점을 기억하세요. 이 요청은 데이터를 corp-resources-public으로 추출하려는 시도로 간주되어 거부됩니다.

이 예시에서는 데이터 복사와 같은 개념 작업이 Cloud Storage, BigQuery, Bigtable과 같은 서로 다른 스토리지 시스템의 데이터에 액세스하려고 여러 번 시도할 수 있음을 보여줍니다. 작업이 수행되는 방법에 따라 생성된 감사 로그 레코드가 원본 사용자 명령어와 다릅니다. 또한 지정된 서비스 내에서 여러 검사가 수행되고 잠재적으로 실패할 때, 생성된 감사 로그 레코드는 원본 사용자 명령어와 다르게 보입니다.

프로젝트에서 Dataproc 작업 읽기

이 예시에서는 Dataproc과 같은 데이터 처리 서비스를 사용할 때 발생하는 간접 VPC 서비스 제어 오류를 디버깅하는 방법을 보여줍니다.

이 예시에서 Dataproc 클러스터는 VPC 서비스 제어로 보호되는 프로젝트에서 실행되고 있습니다. Hello-world.py는 경계 내에 있는 Cloud Storage 버킷의 데이터에 액세스한 후 경계 외부에 있는 다른 버킷에 쓰려고 시도하는 pyspark 작업입니다. VPC 서비스 제어는 경계 외부의 버킷에 데이터를 쓰는 작업을 차단합니다.

다음 명령어는 Hello-world.py를 실행하는 데 사용됩니다.

gcloud dataproc jobs submit pyspark hello-world.py --cluster test-cluster-new2

이 명령어는 다음 출력을 반환합니다.

Job [50f16ca8-5102-442b-a545-eed5e4f5f5da] submitted.
Waiting for job output...
18/11/29 00:31:34 INFO org.spark_project.jetty.util.log: Logging initialized @2552ms
18/11/29 00:31:34 INFO org.spark_project.jetty.server.Server: jetty-9.3.z-SNAPSHOT
18/11/29 00:31:34 INFO org.spark_project.jetty.server.Server: Started @2640ms
18/11/29 00:31:34 INFO org.spark_project.jetty.server.AbstractConnector: Started ServerConnector@1f1c18ec{HTTP/1.1,[http/1.1]}{0.0.0.0:4040}
18/11/29 00:31:34 INFO com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystemBase: GHFS version: 1.6.4-hadoop2
18/11/29 00:31:35 INFO org.apache.hadoop.yarn.client.RMProxy: Connecting to ResourceManager at test-cluster-new2-m/10.246.0.3:8032
18/11/29 00:31:37 INFO org.apache.hadoop.yarn.client.api.impl.YarnClientImpl: Submitted application application_1522454176466_0005
Traceback (most recent call last):
  File "/tmp/50f16ca8-5102-442b-a545-eed5e4f5f5da/hello-world.py", line 8, in <module>
    lear.saveAsTextFile("gs://corp-resources-public-1/out.txt")
  File "/usr/lib/spark/python/lib/pyspark.zip/pyspark/rdd.py", line 1553, in saveAsTextFile
  File "/usr/lib/spark/python/lib/py4j-0.10.4-src.zip/py4j/java_gateway.py", line 1133, in __call__
  File "/usr/lib/spark/python/lib/py4j-0.10.4-src.zip/py4j/protocol.py", line 319, in get_return_value
py4j.protocol.Py4JJavaError: An error occurred while calling o49.saveAsTextFile.
: java.io.IOException: Error accessing: bucket: corp-resources-public-1, object: out.txt
    at com.google.cloud.hadoop.gcsio.GoogleCloudStorageImpl.wrapException(GoogleCloudStorageImpl.java:1767)
$sp(PairRDDFunctions.scala:961)

 (truncated)

Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Request violates VPC Service Controls.",
    "reason" : "vpcServiceControls"
  } ],
  "message" : "Request violates VPC Service Controls."
}
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)

 (truncated)

18/11/29 00:31:43 INFO org.spark_project.jetty.server.AbstractConnector: Stopped Spark@1f1c18ec{HTTP/1.1,[http/1.1]}{0.0.0.0:4040}
ERROR: (gcloud.dataproc.jobs.submit.pyspark) Job [50f16ca8-5102-442b-a545-eed5e4f5f5da] entered state [ERROR] while waiting for [DONE].

saveAsTextFile 메서드가 호출될 때 발생하는 IO 예외에 유의하세요. Cloud Storage는 Request violates VPC Service Controls 메시지와 함께 403 오류를 반환합니다. 이 오류는 Cloud Storage 감사 로그 작업을 검토해야 함을 나타냅니다.

명령어가 실행된 perimeter-network 프로젝트의 감사 로그에는 saveAsTextFile 작업의 감사 로그 레코드가 있습니다.

{
 insertId:  "qdj1o9d1run"
 logName:  "projects/corp-resources-private/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "1004338142803-compute@example.gserviceaccount.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/_/buckets/corp-resources-public-1/objects/out.txt"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "google.storage.BillingRequiredRead"
  requestMetadata: {
   callerIp:  "10.246.0.3"
   callerNetwork:  "//compute.googleapis.com/projects/corp-resources-private/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/1004338142803"
  serviceName:  "storage.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-29T00:31:43.666227930Z"
 resource: {
  labels: {
   method:  "google.storage.BillingRequiredRead"
   project_id:  "corp-resources-private"
   service:  "storage.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-29T00:31:43.608250320Z"
}

감사 로그 제한사항으로 인해 Cloud Storage의 methodName은 실제로 write 작업이지만 Read로 나열됩니다. 감사 로그 레코드는 corp-resources-private 프로젝트의 네트워크가 corp-resources-public-1 버킷에 있는 리소스의 데이터에 액세스하려 했으므로(이 경우 쓰기) 작업이 실패했음을 나타냅니다. Cloud Storage 감사 로그의 제한사항으로 인해 프로젝트 버킷 corp-resources-public-1이 어디에 속하는지 명확하지 않습니다.

corp-resources-public-1이 포함된 프로젝트를 식별하려면 다음 명령어를 사용합니다.

gsutil --debug ls -L -b gs://corp-resources-public-1 2>&1 | grep projectNumber

이 명령어는 다음 출력을 반환합니다.

projectNumber: u'117961063178'

117961063178은 경계 외부에 있는 corp-resources-public 프로젝트입니다. 따라서 실패가 예상됩니다.

제한된 VIP를 사용하는 미지원 서비스

VPC 서비스 제어의 제한된 VIP가 지원되지 않는 API에 액세스하려고 하면 404 오류가 발생합니다. 예를 들어 VPC 서비스 제어가 Cloud DNS를 지원하지 않으면 제한된 VIP를 사용할 때 Cloud DNS API를 사용할 수 없습니다.

예를 들어 다음 명령어를 사용한다고 가정해 보겠습니다.

gcloud dns managed-zones list

이 명령어는 다음 출력을 반환합니다.

ERROR: (gcloud.dns.managed-zones.list) Project [corp-resources-private] not found: <!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 404 (Not Found)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){ #logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){ #logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
  </style>
  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
  <p><b>404.</b> <ins>That's an error.</ins>
  <p>The requested URL <code>/dns/v1/projects/corp-resources-private/managedZones</code> was not found on this server.  <ins>That's all we know.</ins>

VPC 서비스 제어에서 지원하지 않으며 제한된 VIP에서 사용할 수 없는 서비스의 경우 이러한 유형의 오류가 발생할 수 있습니다. VPC 서비스 제어에서 지원하는 서비스에서 이 오류가 발생할 경우 서비스의 알려진 서비스 제한사항을 통해 알려진 제한사항인지 확인하는 것이 좋습니다. 그렇지 않으면 이 문제를 보고해야 합니다.

경계 외부의 프로젝트로 로그 내보내기

이 예시에서는 VPC 서비스 제어가 로그 내보내기를 차단합니다. 내보내기 대상인 corp-resources-public 프로젝트는 VPC 서비스 제어 경계 외부에 있으며 perimeter-network 프로젝트에서 생성된 싱크는 경계 내부에 있습니다.

예를 들어 다음 명령어를 사용한다고 가정해 보겠습니다.

gcloud logging sinks describe example-sink

이 명령어는 다음 출력을 반환합니다.

destination: bigquery.googleapis.com/projects/corp-resources-public/datasets/logs
filter: |-
  resource.type="audited_resource"
  resource.labels.service="bigquery.googleapis.com"
name: example-sink
outputVersionFormat: V2
writerIdentity: serviceAccount:p927005422713-439672@gcp-sa-logging.iam.gserviceaccount.com

다음 감사 로그 레코드가 생성됩니다.

{
 insertId:  "e5i2i8cbqw"
 logName:  "projects/perimeter-network/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "p927005422713-439672@gcp-sa-logging.iam.gserviceaccount.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "corp-resources-public"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "google.cloud.bigquery.v2.TableDataService.InsertAll"
  requestMetadata: {
   callerIp:  "2002:a49:8c51::"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/927005422713"
  serviceName:  "bigquery.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-29T17:32:19.287138882Z"
 resource: {
  labels: {
   method:  "google.cloud.bigquery.v2.TableDataService.InsertAll"
   project_id:  "perimeter-network"
   service:  "bigquery.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-29T17:32:19.054662413Z"
}

Logging이 아닌 BigQuery에 대한 감사 로그 레코드가 생성됩니다. Logging이 데이터를 쓰려고 시도하는 싱크 서비스가 BigQuery이기 때문입니다.

corp-resources-publicperimeter-network를 보호하는 경계 외부에 있으므로 내보내기가 실패합니다.

이 예시에서는 GCP 서비스가 p927005422713-439672@gcp-sa-logging.iam.gserviceaccount.com과 같은 GCP 내부에 있는 GCP 관리형 서비스 계정을 사용하여 다른 GCP 서비스를 호출할 경우 요청의 '네트워크 프로젝트'(이 경우 perimeter-network)가 해당 ID에서 파생됩니다. 동일한 ID는 로그 내보내기 리소스 자체를 나타냅니다.

이 패턴은 Google Cloud에서 일반적이며 서비스 간 상호작용의 수많은 사례에 적용됩니다.

Cloud Storage로 BigQuery 추출

이 예시에서는 실패한 BigQuery 압축을 Cloud Storage로 디버깅하는 방법을 설명합니다.

이 예시에서 corp-resources-privateperimeter-network는 서비스 경계로 보호되는 프로젝트입니다. corp-resources-public은 경계 외부에 있는 프로젝트입니다.

다음 명령어를 사용했다고 가정해 보겠습니다.

bq extract babynames.yob2000

이 명령어는 다음 출력을 반환합니다.

gs://corp-resources-public-1/export.txt
Waiting on bqjob_r47ee34109d02b41_000001676b27157c_1 ... (1s) Current status: DONE
BigQuery error in extract operation: Error processing job 'corp-resources-private:bqjob_r47ee34109d02b41_000001676b27157c_1': Access
Denied: BigQuery BigQuery: Permission denied while writing data.

이 경우 오류가 특별히 VPC 서비스 제어와 연관된 것으로 나타나지 않습니다. Identity and Access Management 오류가 있으면 비슷한 오류가 표시됩니다.

다음 감사 로그 레코드가 생성됩니다.

{
 insertId:  "4gbh6pe8jld7"
 logName:  "projects/corp-resources-private/logs/cloudaudit.googleapis.com%2Fdata_access"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "storage-accessing@example.iam.gserviceaccount.com"
  }
  methodName:  "jobservice.jobcompleted"
  requestMetadata: {
   callerIp:  "10.5.0.4"
   callerNetwork:  "//compute.googleapis.com/projects/perimeter-network/global/networks/__unknown__"
   callerSuppliedUserAgent:  "google-api-python-client/1.6.5 (gzip),gzip(gfe)"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/corp-resources-private/jobs/bqjob_r47ee34109d02b41_000001676b27157c_1"
  serviceData: {
   @type:  "type.googleapis.com/google.cloud.bigquery.logging.v1.AuditData"
   jobCompletedEvent: {
    eventName:  "extract_job_completed"
    job: {
     jobConfiguration: {
      extract: {
       destinationUris: [
        0:  "gs://corp-resources-public-1/export.txt"
       ]
       sourceTable: {
        datasetId:  "babynames"
        projectId:  "corp-resources-private"
        tableId:  "yob2000"
       }
      }
     }
     jobName: {
      jobId:  "bqjob_r47ee34109d02b41_000001676b27157c_1"
      location:  "US"
      projectId:  "corp-resources-private"
     }
     jobStatistics: {
      createTime:  "2018-12-01T19:03:03.908Z"
      endTime:  "2018-12-01T19:03:05.494Z"
      startTime:  "2018-12-01T19:03:04.013Z"
     }
     jobStatus: {
      additionalErrors: [
       0: {
        code:  7
        message:  "Access Denied: BigQuery BigQuery: Permission denied while writing data."
       }
      ]
      error: {
       code:  7
       message:  "Access Denied: BigQuery BigQuery: Permission denied while writing data."
      }
      state:  "DONE"
     }
    }
   }
  }
  serviceName:  "bigquery.googleapis.com"
  status: {
   code:  7
   message:  "Access Denied: BigQuery BigQuery: Permission denied while writing data."
  }
 }
 receiveTimestamp:  "2018-12-01T19:03:05.532169998Z"
 resource: {
  labels: {
   project_id:  "corp-resources-private"
  }
  type:  "bigquery_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-12-01T19:03:05.503Z"
}

이 감사 로그 레코드에서 storage-accessing@example.iam.gserviceaccount.com은 작업을 실행하려고 시도하는 ID로 식별됩니다. 이 예시에서는 storage-accessing@example.iam.gserviceaccount.com에 명령어를 실행하는 데 필요한 IAM 권한이 있다고 가정합니다.

IAM 권한이 문제가 아니므로 다음 단계는 VPC 서비스 제어 오류를 확인하는 것입니다.

대상 서비스(Cloud Storage)의 감사 로그 레코드에는 실패의 자세한 이유가 있습니다.

{
 insertId:  "1bq397kcfj1"
 logName:  "projects/corp-resources-private/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "storage-accessing@example.iam.gserviceaccount.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/1004338142803"
    1:  "projects/_/buckets/corp-resources-public-1"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "google.storage.BillingRequiredRead"
  requestMetadata: {
   callerIp:  "10.5.0.4"
   callerNetwork:  "//compute.googleapis.com/projects/perimeter-network/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/1004338142803"
  serviceName:  "storage.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-12-01T19:03:05.617451586Z"
 resource: {
  labels: {
   method:  "google.storage.BillingRequiredRead"
   project_id:  "corp-resources-private"
   service:  "storage.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-12-01T19:03:05.420005215Z"
}

이 로그에서 1004338142803(corp-resources-private-1) 및 corp-resources-public이라는 두 프로젝트는 명령어를 완성하는 데 사용된 것이 분명합니다. 이러한 프로젝트는 경계를 공유하지 않으므로 추출 작업이 실패합니다.

이 예시에서는 복잡한 다중 서비스 작업에서 소스 서비스와 대상 서비스의 감사 로그에 유용한 디버깅 데이터가 포함될 수 있음을 보여줍니다.