Criar recursos do Google Cloud em conformidade com políticas

Neste tutorial, mostramos como os administradores da plataforma podem usar as políticas do Policy Controller para controlar a criação de recursos do Google Cloud usando o Config Connector.

Esta página é destinada a administradores e operadores de TI que querem garantir que todos os recursos executados na plataforma de nuvem atendam a requisitos de conformidade organizacional, fornecendo e mantendo automação para auditar ou aplicar, e que gerenciam o ciclo de vida da infraestrutura de tecnologia subjacente. Para saber mais sobre papéis comuns e tarefas de exemplo que mencionamos no conteúdo doGoogle Cloud , consulte Tarefas e funções de usuário comuns do GKE.

As instruções neste tutorial pressupõem que você já tem um conhecimento básico do Kubernetes ou do Google Kubernetes Engine (GKE). No tutorial, você terá que definir uma política que restringe os locais permitidos para buckets do Cloud Storage.

O Controlador de Políticas verifica, audita e aplica a conformidade de recursos do cluster do Kubernetes com políticas relacionadas a segurança, regulamentos ou regras de negócios. O Controlador de Políticas foi desenvolvido com base no projeto de código aberto do OPA Gatekeeper.

O Config Connector cria e gerencia o ciclo de vida dos recursos doGoogle Cloud , descrevendo-os como recursos personalizados do Kubernetes. Para criar um recurso Google Cloud , crie um recurso do Kubernetes em um namespace gerenciado pelo Config Connector. No exemplo a seguir, veja como descrever um bucket do Cloud Storage usando o Config Connector:

apiVersion: storage.cnrm.cloud.google.com/v1beta1
kind: StorageBucket
metadata:
  name: my-bucket
spec:
  location: us-east1

Ao gerenciar os recursos do Google Cloud com o Config Connector, é possível aplicar as políticas do Policy Controller a esses recursos ao criá-los no cluster do Google Kubernetes Engine. Essas políticas permitem que você evite ou denuncie ações que criam ou modificam recursos de maneira que violam suas políticas. Por exemplo, é possível aplicar uma política que restringe os locais dos buckets do Cloud Storage.

Essa abordagem, com base no modelo de recursos do Kubernetes (KRM), permite usar um conjunto consistente de ferramentas e fluxos de trabalho para gerenciar os recursos do Kubernetes e do Google Cloud . Neste tutorial, demonstramos como realizar as seguintes tarefas:

  • Defina políticas que regem seus recursos do Google Cloud .
  • Implementar controles que impeçam que desenvolvedores e administradores criem recursos do Google Cloud que violem suas políticas.
  • Implementar controles que auditem os recursos atuais do Google Cloud em relação às políticas, mesmo que você tenha criado esses recursos fora do Config Connector.
  • Forneça feedback rápido aos desenvolvedores e administradores conforme eles criarem e atualizarem as definições dos recursos.
  • Valide as definições de recursos Google Cloud em relação às suas políticas antes de tentar aplicá-las a um cluster do Kubernetes.

Criar um cluster do GKE

  1. No Cloud Shell, crie um cluster do GKE com o complemento Config Connector e a Federação de Identidade da Carga de Trabalho para GKE:

    gcloud container clusters create CLUSTER_NAME \
      --addons ConfigConnector \
      --enable-ip-alias \
      --num-nodes 4 \
      --release-channel regular \
      --scopes cloud-platform \
      --workload-pool $GOOGLE_CLOUD_PROJECT. \
      --zone ZONE
    

    Troque o seguinte:

    • CLUSTER_NAME: o nome do cluster que você quer usar para este projeto, por exemplo, cnrm-gatekeeper-tutorial.
    • ZONE: uma zona do Compute Engine próxima ao seu local, por exemplo, asia-southeast1-b.

    O complemento Config Connector instala definições de recursos personalizados (CRDs) para recursos do Google Cloud no seu cluster do GKE.

  2. (Opcional) Se você usa um cluster particular no próprio ambiente, adicione uma regra de firewall para permitir que o plano de controle do cluster do GKE se conecte ao webhook do Controlador de Políticas:

    gcloud compute firewall-rules create allow-cluster-control-plane-tcp-8443 \
      --allow tcp:8443 \
      --network default \
      --source-ranges CONTROL_PLANE_CIDR \
      --target-tags NODE_TAG
    

    Troque o seguinte:

    • CONTROL_PLANE_CIDR: o intervalo de IP do seu plano de controle do cluster do GKE, por exemplo, 172.16.0.16/28.
    • NODE_TAG: uma tag aplicada a todos os nós no cluster do GKE.

    Essa regra de firewall opcional é necessária para que o webhook do Controlador de Políticas funcione quando o cluster usa nós privados.

Configurar o Config Connector

O Google Cloud projeto em que você instala o Config Connector é conhecido como projeto host. Os projetos em que você usa o Config Connector para gerenciar recursos são conhecidos como projetos gerenciados. Neste tutorial, você vai usar o Config Connector para criar recursos doGoogle Cloud no mesmo projeto que o cluster do GKE. Assim, o projeto host e o gerenciado são o mesmo projeto.

  1. No Cloud Shell, crie uma conta de serviço do Google para o Config Connector:

    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name "Config Connector Gatekeeper tutorial"
    

    Substitua SERVICE_ACCOUNT_NAME pelo nome que você quer usar para esta conta de serviço, por exemplo, cnrm-gatekeeper-tutorial. O Config Connector usa essa conta de serviço do Google para criar recursos no seu projeto gerenciado.

  2. Conceda o Papel de administrador de armazenamento à conta de serviço do Google:

    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
      --member "serviceAccount:SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT." \
      --role roles/storage.admin
    

    Neste tutorial, você vai usar o papel de Administrador do Storage porque o Config Connector é usado para criar buckets do Cloud Storage. No seu ambiente, conceda as funções necessárias para gerenciar os recursos do Google Cloud que você quer criar para o Config Connector. Para mais informações sobre papéis predefinidos, consulte Como entender os papéis na documentação do IAM.

  3. Crie um namespace do Kubernetes para os recursos do Config Connector criados neste tutorial:

    kubectl create namespace NAMESPACE
    

    Substitua NAMESPACE pelo namespace do Kubernetes que você quer usar no tutorial, por exemplo, tutorial.

  4. Anote o namespace para especificar qual projeto o Config Connector deve usar para criar recursos Google Cloud (o projeto gerenciado):

    kubectl annotate namespace NAMESPACE \
        cnrm.cloud.google.com/project-id=$GOOGLE_CLOUD_PROJECT
    
  5. Crie um recurso ConfigConnectorContext que ative o Config Connector para o namespace do Kubernetes e associe-o à conta de serviço do Google que você criou:

    cat << EOF | kubectl apply -f -
    apiVersion: core.cnrm.cloud.google.com/v1beta1
    kind: ConfigConnectorContext
    metadata:
      name: configconnectorcontext.core.cnrm.cloud.google.com
      namespace: NAMESPACE
    spec:
      googleServiceAccount: SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.
    EOF
    

    Quando você cria o recurso ConfigConnectorContext, o Config Connector cria uma conta de serviço do Kubernetes e um StatefulSet no namespace cnrm-system para gerenciar os recursos do Config Connector no seu namespace.

  6. Aguarde o pod do controlador do Config Connector para seu namespace:

    kubectl wait --namespace cnrm-system --for=condition=Ready pod \
      -l cnrm.cloud.google.com/component=cnrm-controller-manager,cnrm.cloud.google.com/scoped-namespace=NAMESPACE
    

    Quando o pod estiver pronto, o prompt do Cloud Shell será exibido. Se você receber a mensagem error: no matching resources found, aguarde um minuto e tente novamente.

  7. Vincule sua conta de serviço do Config Connector do Kubernetes à conta de serviço do Google criando uma vinculação de política do IAM:

    gcloud iam service-accounts add-iam-policy-binding \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT. \
      --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.[cnrm-system/cnrm-controller-manager-NAMESPACE]" \
      --role roles/iam.workloadIdentityUser
    

    Essa vinculação permite que a conta de serviço cnrm-controller-manager-NAMESPACE do Kubernetes no namespace cnrm-system atue como a conta de serviço do Google que você criou.

Instalar o Controlador de Políticas

Instale o Controlador de Políticas seguindo as instruções de instalação.

Use um intervalo de auditoria de 60 segundos.

Criar um recurso Google Cloud usando o Config Connector

  1. No Cloud Shell, crie um manifesto do Config Connector que represente um bucket do Cloud Storage na região us-central1:

    cat << EOF > tutorial-storagebucket-us-central1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-us-central1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: us-central1
      uniformBucketLevelAccess: true
    EOF
    
  2. Para criar o bucket do Cloud Storage, aplique o manifesto:

    kubectl apply -f tutorial-storagebucket-us-central1.yaml
    
  3. Verifique se o Config Connector criou o bucket do Cloud Storage:

    gcloud storage ls | grep tutorial
    

    O resultado será assim:

    gs://tutorial-us-central1-PROJECT_ID/
    

    Essa saída inclui PROJECT_ID, que é o ID do projeto Google Cloud .

    Se você não vir essa resposta, aguarde um minuto e execute a etapa novamente.

Criar uma política

Uma política no Controlador de Políticas é composta de um modelo de restrição e uma restrição. O modelo de restrição contém a lógica da política. A restrição especifica onde a política se aplica e os parâmetros de entrada para a lógica da política.

  1. No Cloud Shell, crie um modelo de restrição que restrinja os locais do bucket do Cloud Storage:

    cat << EOF > tutorial-storagebucket-location-template.yaml
    apiVersion: templates.gatekeeper.sh/v1beta1
    kind: ConstraintTemplate
    metadata:
      name: gcpstoragelocationconstraintv1
    spec:
      crd:
        spec:
          names:
            kind: GCPStorageLocationConstraintV1
          validation:
            openAPIV3Schema:
              properties:
                locations:
                  type: array
                  items:
                    type: string
                exemptions:
                  type: array
                  items:
                    type: string
      targets:
      - target: admission.k8s.gatekeeper.sh
        rego: |
          package gcpstoragelocationconstraintv1
    
          allowedLocation(reviewLocation) {
              locations := input.parameters.locations
              satisfied := [ good | location = locations[_]
                                    good = lower(location) == lower(reviewLocation)]
              any(satisfied)
          }
    
          exempt(reviewName) {
              input.parameters.exemptions[_] == reviewName
          }
    
          violation[{"msg": msg}] {
              bucketName := input.review.object.metadata.name
              bucketLocation := input.review.object.spec.location
              not allowedLocation(bucketLocation)
              not exempt(bucketName)
              msg := sprintf("Cloud Storage bucket <%v> uses a disallowed location <%v>, allowed locations are %v", [bucketName, bucketLocation, input.parameters.locations])
          }
    
          violation[{"msg": msg}] {
              not input.parameters.locations
              bucketName := input.review.object.metadata.name
              msg := sprintf("No permitted locations provided in constraint for Cloud Storage bucket <%v>", [bucketName])
          }
    EOF
    
  2. Aplique o modelo para criar o bucket do Cloud Storage:

    kubectl apply -f tutorial-storagebucket-location-template.yaml
    
  3. Crie uma restrição que permita apenas buckets nas regiões de Singapura e Jacarta (asia-southeast1 e asia-southeast2). A restrição se aplica ao namespace criado anteriormente. Ele isenta o bucket padrão do Cloud Storage para o Cloud Build.

    cat << EOF > tutorial-storagebucket-location-constraint.yaml
    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: GCPStorageLocationConstraintV1
    metadata:
      name: singapore-and-jakarta-only
    spec:
      enforcementAction: deny
      match:
        kinds:
        - apiGroups:
          - storage.cnrm.cloud.google.com
          kinds:
          - StorageBucket
        namespaces:
        - NAMESPACE
      parameters:
        locations:
        - asia-southeast1
        - asia-southeast2
        exemptions:
        - ${GOOGLE_CLOUD_PROJECT}_cloudbuild
    EOF
    
  4. Para limitar as zonas em que os buckets podem existir, aplique a restrição:

    kubectl apply -f tutorial-storagebucket-location-constraint.yaml
    

Verificar a política

  1. Crie um manifesto que represente um bucket do Cloud Storage em um local que não seja permitido (us-west1):

    cat << EOF > tutorial-storagebucket-us-west1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-us-west1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: us-west1
      uniformBucketLevelAccess: true
    EOF
    
  2. Para criar o bucket do Cloud Storage, aplique o manifesto:

    kubectl apply -f tutorial-storagebucket-us-west1.yaml
    

    O resultado será assim:

    Error from server ([singapore-and-jakarta-only] Cloud Storage bucket
    <tutorial-us-west1-PROJECT_ID> uses a disallowed location
    <us-west1>, allowed locations are ["asia-southeast1",
    "asia-southeast2"]): error when creating
    "tutorial-storagebucket-us-west1.yaml": admission webhook
    "validation.gatekeeper.sh" denied the request: [singapore-and-jakarta-only]
    Cloud Storage bucket <tutorial-us-west1-PROJECT_ID> uses a
    disallowed location <us-west1>, allowed locations are
    ["asia-southeast1", "asia-southeast2"]
    
  3. Opcional: é possível ver um registro da decisão de negar a solicitação nos registros de auditoria do Cloud. Consulte os registros de atividade do administrador do seu projeto:

    gcloud logging read --limit=1 \
        "logName=\"projects/$GOOGLE_CLOUD_PROJECT/logs/cloudaudit.googleapis.com%2Factivity\""'
        resource.type="k8s_cluster"
        resource.labels.cluster_name="CLUSTER_NAME"
        resource.labels.location="ZONE"
        protoPayload.authenticationInfo.principalEmail!~"system:serviceaccount:cnrm-system:.*"
        protoPayload.methodName:"com.google.cloud.cnrm."
        protoPayload.status.code=7'
    

    O resultado será semelhante ao exemplo a seguir:

    insertId: 3c6940bb-de14-4d18-ac4d-9a6becc70828
    labels:
      authorization.k8s.io/decision: allow
      authorization.k8s.io/reason: ''
      mutation.webhook.admission.k8s.io/round_0_index_0: '{"configuration":"mutating-webhook.cnrm.cloud.google.com","webhook":"container-annotation-handler.cnrm.cloud.google.com","mutated":true}'
      mutation.webhook.admission.k8s.io/round_0_index_1: '{"configuration":"mutating-webhook.cnrm.cloud.google.com","webhook":"management-conflict-annotation-defaulter.cnrm.cloud.google.com","mutated":true}'
    logName: projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Factivity
    operation:
      first: true
      id: 3c6940bb-de14-4d18-ac4d-9a6becc70828
      last: true
      producer: k8s.io
    protoPayload:
      '@type': type.googleapis.com/google.cloud.audit.AuditLog
      authenticationInfo:
        principalEmail: user@example.com
      authorizationInfo:
      - permission: com.google.cloud.cnrm.storage.v1beta1.storagebuckets.create
        resource: storage.cnrm.cloud.google.com/v1beta1/namespaces/NAMESPACE/storagebuckets/tutorial-us-west1-PROJECT_ID
      methodName: com.google.cloud.cnrm.storage.v1beta1.storagebuckets.create
      requestMetadata:
        callerIp: 203.0.113.1
        callerSuppliedUserAgent: kubectl/v1.21.1 (linux/amd64) kubernetes/5e58841
      resourceName: storage.cnrm.cloud.google.com/v1beta1/namespaces/NAMESPACE/storagebuckets/tutorial-us-west1-PROJECT_ID
      serviceName: k8s.io
      status:
        code: 7
        message: Forbidden
    receiveTimestamp: '2021-05-21T06:56:24.940264678Z'
    resource:
      labels:
        cluster_name: CLUSTER_NAME
        location: CLUSTER_ZONE
        project_id: PROJECT_ID
      type: k8s_cluster
    timestamp: '2021-05-21T06:56:09.060635Z'

    O campo methodName mostra a tentativa de operação, resourceName mostra o nome completo do recurso do Config Connector e a seção status mostra que a solicitação falhou, com um código de erro 7 e uma mensagem Forbidden.

  4. Crie um manifesto que represente um bucket do Cloud Storage em um local permitido (asia-southeast1):

    cat << EOF > tutorial-storagebucket-asia-southeast1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-asia-southeast1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: asia-southeast1
      uniformBucketLevelAccess: true
    EOF
    
  5. Para criar o bucket do Cloud Storage, aplique o manifesto:

    kubectl apply -f tutorial-storagebucket-asia-southeast1.yaml
    

    O resultado será assim:

    storagebucket.storage.cnrm.cloud.google.com/tutorial-asia-southeast1-PROJECT_ID created
    

    Essa saída inclui PROJECT_ID, que é o ID do projeto Google Cloud .

  6. Verifique se o Config Connector criou o bucket do Cloud Storage:

    gcloud storage ls | grep tutorial
    

    O resultado será assim:

    gs://tutorial-asia-southeast1-PROJECT_ID/
    gs://tutorial-us-central1-PROJECT_ID/
    

    Se você não vir essa resposta, aguarde um minuto e execute esta etapa novamente.

Restrições de auditoria

O controlador de auditoria no Controlador de Políticas avalia periodicamente os recursos em relação às restrições deles. O controlador detecta violações de política de recursos criados antes da restrição e de recursos criados fora do Config Connector.

  1. No Cloud Shell, visualize as violações de todas as restrições que usam o modelo de restrição GCPStorageLocationConstraintV1:

    kubectl get gcpstoragelocationconstraintv1 -o json \
      | jq '.items[].status.violations'
    

    O resultado será assim:

    [
      {
        "enforcementAction": "deny",
        "kind": "StorageBucket",
        "message": "Cloud Storage bucket <tutorial-us-central1-PROJECT_ID>
        uses a disallowed location <us-central1>, allowed locations are
        \"asia-southeast1\", \"asia-southeast2\"",
        "name": "tutorial-us-central1-PROJECT_ID",
        "namespace": "NAMESPACE"
      }
    ]
    

    Você verá o bucket do Cloud Storage criado em us-central1 antes de ter criado a restrição.

Validar recursos durante o desenvolvimento

Durante as versões de desenvolvimento contínuo e de integração contínua, é útil validar os recursos em relação às restrições antes de aplicar esses recursos ao cluster do GKE. A validação fornece feedback rápido e permite que você descubra problemas com recursos e restrições antecipadamente. Nestas etapas, mostramos como validar recursos com o kpt. A ferramenta de linha de comando kpt permite gerenciar e aplicar seus manifestos de recursos do Kubernetes.

  1. No Cloud Shell, execute a função de KRM gatekeeper usando kpt:

    kpt fn eval . --image=gcr.io/kpt-fn/gatekeeper:v0.2 --truncate-output=false
    

    Uma função de KRM é um programa que pode modificar ou validar recursos do Kubernetes armazenados no sistema de arquivos local como arquivos YAML. A função do KRM gatekeeper valida os recursos do bucket do Cloud Storage do Config Connector em relação à política do Gatekeeper. A função do KRM gatekeeper é empacotada como uma imagem de contêiner disponível no Artifact Registry.

    A função informa que os arquivos de manifesto para buckets do Cloud Storage nas regiões us-central1 e us-west1 violam a restrição.

    O resultado será assim:

    [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0.2"
    [FAIL] "gcr.io/kpt-fn/gatekeeper:v0.2"
      Results:
        [ERROR] Cloud Storage bucket <tutorial-us-central1-PROJECT_ID> uses a disallowed location <us-central1>, allowed locations are ["asia-southeast1", "asia-southeast2"] violatedConstraint: singapore-and-jakarta-only in object "storage.cnrm.cloud.google.com/v1beta1/StorageBucket/tutorial/tutorial-us-central1-GOOGLE_CLOUD_PROJECT" in file "tutorial-storagebucket-us-central1.yaml"
        [ERROR] Cloud Storage bucket <tutorial-us-west1-PROJECT_ID> uses a disallowed location <us-west1>, allowed locations are ["asia-southeast1", "asia-southeast2"] violatedConstraint: singapore-and-jakarta-only in object "storage.cnrm.cloud.google.com/v1beta1/StorageBucket/tutorial/tutorial-us-west1-GOOGLE_CLOUD_PROJECT" in file "tutorial-storagebucket-us-west1.yaml"
      Stderr:
        "[error] storage.cnrm.cloud.google.com/v1beta1/StorageBucket/test/tutorial-us-central1-PROJECT_ID : Cloud Storage bucket <tutorial-us-central1-PROJECT_ID> uses a disallowed location <us-central1>, allowed locations are [\"asia-southeast1\", \"asia-southeast2\"]"
        "violatedConstraint: singapore-and-jakarta-only"
        ""
        "[error] storage.cnrm.cloud.google.com/v1beta1/StorageBucket/test/tutorial-us-west1-PROJECT_IDT : Cloud Storage bucket <tutorial-us-west1-PROJECT_IDgt; uses a disallowed location <us-west1>, allowed locations are [\"asia-southeast1\", \"asia-southeast2\"]"
        "violatedConstraint: singapore-and-jakarta-only"
        ""
      Exit code: 1
    

Validar recursos criados fora do Config Connector

É possível validar recursos Google Cloud criados fora do Config Connector exportando os recursos. Depois de exportar os recursos, use uma das opções a seguir para avaliar as políticas do Controlador de Políticas em relação aos recursos exportados:

  • Valide os recursos usando a função KRM gatekeeper.

  • Importe os recursos para o Config Connector.

Para exportar os recursos, use o Inventário de recursos do Cloud.

  1. No Cloud Shell, ative a API Cloud Asset:

    gcloud services enable cloudasset.googleapis.com
    
  2. Exclua os arquivos de manifesto de recursos do Kubernetes para os intervalos do Cloud Storage em us-central1 e us-west1:

    rm tutorial-storagebucket-us-*.yaml
    
  3. Exporte todos os recursos do Cloud Storage no projeto atual e armazene a saída em um arquivo chamado export.yaml:

    gcloud beta resource-config bulk-export \
      --project $GOOGLE_CLOUD_PROJECT \
      --resource-format krm \
      --resource-types StorageBucket > export.yaml
    

    O resultado será semelhante ao exemplo a seguir:

    Exporting resource configurations to stdout...
    
    Export complete.
    
  4. Crie um pipeline de kpt encadeando funções do KRM. Ele valida os recursos no diretório atual em relação à política de localização do bucket do Cloud Storage:

    kpt fn source . \
      | kpt fn eval - --image=gcr.io/kpt-fn/set-namespace:v0.1 -- namespace=NAMESPACE \
      | kpt fn eval - --image=gcr.io/kpt-fn/gatekeeper:v0.2 --truncate-output=false
    

    Os recursos exportados não têm um valor para o atributo de metadados namespace. Esse pipeline usa uma função do KRM chamada set-namespace para definir o valor namespace de todos os recursos.

    A saída é semelhante a esta e mostra violações para os recursos exportados:

    [RUNNING] "gcr.io/kpt-fn/set-namespace:v0.1"
    [PASS] "gcr.io/kpt-fn/set-namespace:v0.1"
    [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0.2"
    [FAIL] "gcr.io/kpt-fn/gatekeeper:v0.2"
      Results:
        [ERROR] Cloud Storage bucket <tutorial-us-central1-PROJECT_ID> uses a disallowed location <us-central1>, allowed locations are ["asia-southeast1", "asia-southeast2"] violatedConstraint: singapore-and-jakarta-only in object "storage.cnrm.cloud.google.com/v1beta1/StorageBucket/tutorial/tutorial-us-central1-GOOGLE_CLOUD_PROJECT" in file "export.yaml"
      Stderr:
        "[error] storage.cnrm.cloud.google.com/v1beta1/StorageBucket/test/tutorial-us-central1-PROJECT_ID : Cloud Storage bucket <tutorial-us-central1-PROJECT_ID> uses a disallowed location <us-central1>, allowed locations are [\"asia-southeast1\", \"asia-southeast2\"]"
        "violatedConstraint: singapore-and-jakarta-only"
        ""
      Exit code: 1
    

    Se o projeto Google Cloud contiver buckets do Cloud Storage criados antes de trabalhar neste tutorial e o local deles violar a restrição, os buckets criados anteriormente aparecerão na saída.

Parabéns, você configurou uma política que rege o local permitido dos buckets do Cloud Storage. O tutorial foi concluído. Agora você pode continuar adicionando suas próprias políticas para outros recursos do Google Cloud.

Solução de problemas

Se o Config Connector não criar os recursos Google Cloud esperados, use o seguinte comando no Cloud Shell para visualizar os registros do gerenciador de controladores do Config Connector:

kubectl logs --namespace cnrm-system --container manager \
  --selector cnrm.cloud.google.com/component=cnrm-controller-manager,cnrm.cloud.google.com/scoped-namespace=NAMESPACE

Se o Controlador de Políticas não aplicar as políticas corretamente, use o comando a seguir para visualizar os registros do gerenciador de controladores:

kubectl logs deployment/gatekeeper-controller-manager \
  --namespace gatekeeper-system

Se o Controlador de Políticas não relatar violações no campo status dos objetos de restrição, veja os registros do controlador de auditoria usando este comando:

kubectl logs deployment/gatekeeper-audit --namespace gatekeeper-system

Se você tiver problemas ao seguir este tutorial, recomendamos que consulte estes documentos: