Criar recursos do Google Cloud em conformidade com a política

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

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

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

O Policy Controller 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 Policy Controller 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 do Google Cloud, descrevendo-os como recursos personalizados do Kubernetes. Para criar um recurso do 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 GKE. 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, na sigla em inglês), 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:

  • Definir 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.
  • Validar as definições de recursos do Google Cloud em relação às suas políticas antes de tentar aplicá-las a um cluster do Kubernetes.

Objetivos

  • Criar um cluster do GKE que inclua o complemento Config Connector.
  • Instalar o Policy Controller.
  • Criar uma política para restringir os locais de bucket permitidos do Cloud Storage.
  • Verificar se a política impede a criação de buckets do Cloud Storage em locais não permitidos.
  • Avaliar a conformidade de políticas da definição de bucket do Cloud Storage durante o desenvolvimento.
  • Auditar os buckets do Cloud Storage existentes para garantir a conformidade com as políticas.

Custos

Neste tutorial, usamos os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Antes de começar

  1. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  2. Verifique se o faturamento está ativado para seu projeto na nuvem. Saiba como verificar se o faturamento está ativado em um projeto.

  3. No Console do Google Cloud, ative o Cloud Shell.

    Ativar o Cloud Shell

  4. No Cloud Shell, defina o projeto do Google Cloud que você quer usar neste tutorial:

    gcloud config set project PROJECT_ID
    

    Substitua PROJECT_ID pelo ID do projeto do Cloud do seu projeto. Quando você executa esse comando, o Cloud Shell cria uma variável de ambiente exportada chamada GOOGLE_CLOUD_PROJECT que contém o ID do projeto. Se você não usa o Cloud Shell, crie a variável de ambiente com este comando:

    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value core/project)
    
  5. Ative a API GKE:

    gcloud services enable container.googleapis.com
    
  6. Crie um diretório para armazenar os arquivos criados neste tutorial:

    mkdir -p ~/cnrm-gatekeeper-tutorial
    
  7. Acesse o diretório que você criou:

    cd ~/cnrm-gatekeeper-tutorial
    

crie um cluster do GKE

  1. No Cloud Shell, crie um cluster do GKE com o complemento Config Connector e a Identidade da carga de trabalho:

    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.svc.id.goog \
      --zone ZONE
    

    Substitua:

    • 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 do Config Connector instala definições de recursos personalizados (CRDs) para recursos do Google Cloud no 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 Policy Controller:

    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
    

    Substitua:

    • 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 Policy Controller funcione quando o cluster usa nós privados.

Configurar o Config Connector

O projeto do Google Cloud 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ê usará o Config Connector para criar recursos do Google Cloud no mesmo projeto que o cluster do GKE. Assim, o projeto host e o projeto 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 do Storage à conta de serviço do Google:

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

    Neste tutorial, você usa o papel de Administrador do Storage porque usa o Config Connector para criar buckets do Cloud Storage. No seu ambiente, conceda os papéis necessários 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 do 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.iam.gserviceaccount.com
    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.iam.gserviceaccount.com \
      --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[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 Policy Controller

Instale o Policy Controller seguindo as instruções de instalação.

Use um intervalo de auditoria de 60 segundos.

Criar um recurso do 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:

    gsutil ls | grep tutorial
    

    O resultado será assim:

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

    Esta saída inclui PROJECT_ID, que é o ID do projeto do 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 Policy Controller consiste em 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á assim:

    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 Config Connector e a seção status mostra que a solicitação falhou, com código de erro 7 e 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
    

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

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

    gsutil 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 Policy Controller 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 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 Container 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 os recursos do 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 Policy Controller 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á assim:

    Exporting resource configurations to stdout...
    
    Export complete.
    
  4. Crie um pipeline kpt encadeando funções do KRM. Esse pipeline 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 do Cloud tiver 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 esperados do Google Cloud, 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 Policy Controller não aplicar as políticas corretamente, use o seguinte comando para visualizar os registros do gerenciador de controladores:

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

Se o Policy Controller 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:

Limpeza

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Exclua o projeto

  1. No Console do Google Cloud, acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Se o projeto que você planeja excluir estiver anexado a uma organização, expanda a lista Organização na coluna Nome.
  3. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  4. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

Excluir os recursos

Se você quiser manter o projeto do Cloud usado neste tutorial, exclua os recursos individuais:

  1. No Cloud Shell, exclua a restrição de local do bucket do Cloud Storage:

    kubectl delete -f tutorial-storagebucket-location-constraint.yaml
    
  2. Adicione a anotação cnrm.cloud.google.com/force-destroy com um valor de string de true a todos os recursos storagebucket no namespace gerenciado pelo Config Connector:

    kubectl annotate storagebucket --all --namespace NAMESPACE \
      cnrm.cloud.google.com/force-destroy=true
    

    Essa anotação é uma diretiva que permite que o Config Connector exclua um bucket do Cloud Storage ao excluir o recurso storagebucket correspondente no cluster do GKE, mesmo que o bucket contenha objetos.

  3. Exclua os recursos do Config Connector que representam os buckets do Cloud Storage:

    kubectl delete --namespace NAMESPACE storagebucket --all
    
  4. Exclua o cluster do GKE:

    gcloud container clusters delete CLUSTER_NAME \
      --zone ZONE --async --quiet
    
  5. Exclua a vinculação da política de identidade da carga de trabalho no IAM:

    gcloud iam service-accounts remove-iam-policy-binding \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
      --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[cnrm-system/cnrm-controller-manager-NAMESPACE]" \
      --role roles/iam.workloadIdentityUser
    
  6. Exclua a vinculação de papel de administrador do Cloud Storage para a conta de serviço do Google:

    gcloud projects remove-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
      --member "serviceAccount:SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
      --role roles/storage.admin
    
  7. Exclua a conta de serviço do Google criada para o Config Connector:

    gcloud iam service-accounts delete --quiet \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    

A seguir