gcloud beta terraform vet 빠른 시작

이 빠른 시작에서는 도메인 제한을 시행하는 제약조건을 적용하는 방법을 보여줍니다. 이 제약조건을 테스트하고 내부적으로 오류를 발생시킵니다. 그런 후 도메인이 통과하도록 제약조건을 수정합니다.

시작하기 전에

  • Google Cloud 프로젝트가 필요합니다.
  • 해당 프로젝트에 대해 다음 Identity and Access Management(IAM) 권한이 필요합니다.

    • resourcemanager.projects.getIamPolicy – 이 권한은 조직의 보안 검토자 역할을 통해 부여될 수 있습니다.
    • resourcemanager.projects.get – 이 권한은 조직의 프로젝트 뷰어 역할을 통해 부여될 수 있습니다.

빠른 시작을 위해 이 안내에서는 Terraform 및 클론된 정책 라이브러리 저장소가 사전 설치된 Cloud Shell을 사용합니다. 이 안내에서는 Google Cloud 계정이 이미 있다고 가정합니다.

빠른 시작

  1. Cloud Shell로 이동하여 정책 라이브러리를 클론합니다.

    정책 라이브러리 클론

  2. 샘플 IAM 도메인 제한 제약조건을 policies/constraints 디렉터리에 복사합니다.

    cp samples/iam_service_accounts_only.yaml policies/constraints
    
  3. 터미널에 출력하여 복사한 제약조건을 검사합니다.

    cat policies/constraints/iam_service_accounts_only.yaml
    

    출력 형식은 다음과 같습니다.

    # This constraint checks that all IAM policy members are in the
    # "" domain.
    apiVersion: constraints.gatekeeper.sh/v1alpha1
    kind: GCPIAMAllowedPolicyMemberDomainsConstraintV2
    metadata:
      name: service_accounts_only
      annotations:
        description: Checks that members that have been granted IAM roles belong to allowlisted
          domains.
    spec:
      severity: high
      match:
        target: # {"$ref":"#/definitions/io.k8s.cli.setters.target"}
        - "organizations/**"
      parameters:
        domains:
        - 
    

    하단에서 을 확인합니다. 이렇게 하면 도메인의 구성원만 IAM 정책에 제공되도록 지정됩니다.

  4. 정책이 예상한 대로 작동하는지 확인하려면 현재 디렉터리에 다음 Terraform main.tf 파일을 만듭니다. nano, vim, Cloud Shell 편집기를 사용하여 policy-library/main.tf를 만들 수 있습니다.

    terraform {
      required_providers {
        google = {
          source = "hashicorp/google"
          version = "~> 3.84"
        }
      }
    }
    
    resource "google_project_iam_binding" "sample_iam_binding" {
      project = "PROJECT_ID"
      role    = "roles/viewer"
    
      members = [
        "user:EMAIL_ADDRESS"
      ]
    }
    

    다음을 바꿉니다.

    • PROJECT_ID: 프로젝트 ID입니다.
    • EMAIL_ADDRESS: 샘플 이메일 주소입니다. 모든 유효한 이메일 주소를 사용할 수 있습니다. 예를 들면 user@example.com입니다.
  5. 다음을 사용하여 Terraform을 초기화하고 Terraform 계획을 생성합니다.

    terraform init
    
  6. Terraform 계획을 내보내고, 메시지가 표시되면 승인을 클릭합니다.

    terraform plan -out=test.tfplan
    
  7. Terraform 계획을 JSON으로 변환합니다.

    terraform show -json ./test.tfplan > ./tfplan.json
    
  8. terraform-tools 구성요소를 설치합니다.

    sudo apt-get install google-cloud-sdk-terraform-tools
    
  9. 다음 명령어를 입력하여 Terraform 계획이 정책을 준수하는지 확인합니다.

    gcloud beta terraform vet tfplan.json --policy-library=. --format=json
    

    IAM 정책 binding에 제공한 이메일 주소가 서비스 계정에 속하지 않으므로 이 계획은 설정된 제약조건을 위반합니다.

    [
    {
      "constraint": "GCPIAMAllowedPolicyMemberDomainsConstraintV2.service_accounts_only",
      "constraint_config": {
        "api_version": "constraints.gatekeeper.sh/v1alpha1",
        "kind": "GCPIAMAllowedPolicyMemberDomainsConstraintV2",
        "metadata": {
          "annotations": {
            "description": "Checks that members that have been granted IAM roles belong to allowlisted domains.",
            "validation.gcp.forsetisecurity.org/originalName": "service_accounts_only",
            "validation.gcp.forsetisecurity.org/yamlpath": "policies/constraints/iam_service_accounts_only.yaml"
          },
          "name": "service-accounts-only"
        },
        "spec": {
          "match": {
            "target": [
              "organizations/**"
            ]
          },
          "parameters": {
            "domains": [
              ""
            ]
          },
          "severity": "high"
        }
      },
      "message": "IAM policy for //cloudresourcemanager.googleapis.com/projects/PROJECT_ID contains member from unexpected domain: user:user@example.com",
      "metadata": {
        "ancestry_path": "organizations/ORG_ID/projects/PROJECT_ID",
        "constraint": {
          "annotations": {
            "description": "Checks that members that have been granted IAM roles belong to allowlisted domains.",
            "validation.gcp.forsetisecurity.org/originalName": "service_accounts_only",
            "validation.gcp.forsetisecurity.org/yamlpath": "policies/constraints/iam_service_accounts_only.yaml"
          },
          "labels": {},
          "parameters": {
            "domains": [
              ""
            ]
          }
        },
        "details": {
          "member": "user:user@example.com",
          "resource": "//cloudresourcemanager.googleapis.com/projects/PROJECT_ID"
        }
      },
      "resource": "//cloudresourcemanager.googleapis.com/projects/PROJECT_ID",
      "severity": "high"
    }
    ]
  10. 다른 도메인(이메일)을 허용하려면 policy-library/policies/constraints/iam_service_accounts_only.yaml을 수정하고 이메일 도메인을 도메인 허용 목록에 추가합니다. 다음 예시에서는 example.com이 추가되었지만 고유 이메일 주소의 도메인을 입력할 수 있습니다.

    apiVersion: constraints.gatekeeper.sh/v1alpha1
    kind: GCPIAMAllowedPolicyMemberDomainsConstraintV1
    metadata:
      name: service_accounts_only
    spec:
      severity: high
      match:
        target: ["organizations/**"]
      parameters:
        domains:
          - 
          - example.com
    
  11. 이제 Terraform 계획을 다시 검사하면 위반 사항이 표시되지 않습니다.

    gcloud beta terraform vet tfplan.json --policy-library=. --format=json
    

    예상 출력:

    []

문제 해결

"Error 403: The caller does not have permission, forbidden" 오류가 표시되면 policy-library/main.tf에서 PROJECT_ID를 프로젝트 이름으로 바꾸지 않았거나 지정한 프로젝트에 필요한 권한이 없기 때문입니다.

프로젝트 이름 또는 권한을 수정한 후(resourcemanager.projects.getIamPolicyresourcemanager.projects.get) 다시 돌아가서 Terraform 계획을 내보낸 다음 Terraform 계획을 JSON으로 변환합니다.