Skip to content

Latest commit

 

History

History
 
 

dns-fine-grained-iam

Fine-grained Cloud DNS IAM via Service Directory

This blueprint shows how to leverage Service Directory and Cloud DNS Service Directory private zones, to implement fine-grained IAM controls on DNS by

  • creating a Service Directory namespace with two services and their endpoints
  • creating a Cloud DNS private zone that uses the namespace as its authoritative source
  • creating two service accounts and assigning them the roles/servicedirectory.editor role on the namespace and on one service respectively
  • creating two VMs and setting them to use the two service accounts, so that DNS queries and gcloud commands can be used to verify the setup

The resources created in this blueprint are shown in the high level diagram below:

A companion Medium article has been published for this blueprint, you can refer to it for more details on the context, and the specifics of running the blueprint.

Running the blueprint

Clone this repository or open it in cloud shell, then go through the following steps to create resources:

  • terraform init
  • terraform apply -var project_id=my-project-id

Once done testing, you can clean up resources by running terraform destroy. To persist state, check out the backend.tf.sample file.

Testing the blueprint

The terraform outputs generate preset gcloud compute ssh commands that you can copy and run in the console to connect to each VM. Remember to adapt the testing commands below if you changed the default values for the name, region, or zone_domain variables.

Connect via SSH to the ns VM and query the Service Directory namespace via DNS.

gcloud compute ssh dns-sd-test-ns-1 \
  --zone europe-west1-b \
  --tunnel-through-iap

dig app1.svc.example.org +short
# 127.0.0.2
# 127.0.0.3
# 127.0.0.7
dig app2.svc.example.org +short
# 127.0.0.4
# 127.0.0.5
dig _app1._tcp.app1.svc.example.org srv +short
# 10 10 80 vm1.app1.svc.example.org.
# 10 10 80 vm2.app1.svc.example.org.
# 10 10 80 vm3.app1.svc.example.org.

The DNS answers should match the ones in the comments above, after each command. Note the special format used to query SRV records.

If the above looks good, let's verify that the ns VM service account has edit rights on the namespace by creating a new service, and then verifying it via DNS.

gcloud beta service-directory services create app3 \
  --location europe-west1 \
  --namespace dns-sd-test
# Created service [app3].

gcloud beta service-directory endpoints create vm1 \
  --service app3 \
  --location europe-west1 \
  --namespace dns-sd-test \
  --address 127.0.0.6 \
  --port 80
# Created endpoint [vm1].

dig app3.svc.example.org +short
# 127.0.0.6

Log out from the ns VM and log in to the svc VM, then verify that its service account has no permissions on the whole namespace.

gcloud compute ssh dns-sd-test-svc-1 \
  --zone europe-west1-b \
  --tunnel-through-iap

gcloud beta service-directory services delete app3 \
  --location europe-west1 \
  --namespace dns-sd-test
# Deleted service [app3].
# ERROR: (gcloud.beta.service-directory.services.delete) PERMISSION_DENIED: Permission 'servicedirectory.services.delete' denied on resource 'projects/my-project/locations/europe-west1/namespaces/dns-sd-test/services/app3'.

Ignoring the deleted message which is clearly a bug (the service is still in beta after all), the error message shows that this identity has no rights to operate on the namespace. What it can do is operate on the single service we gave it access to.

gcloud beta service-directory endpoints create vm3 \
  --service app1 \
  --location europe-west1 \
  --namespace dns-sd-test \
  --address 127.0.0.7 \
  --port 80
# Created endpoint [vm3].

dig app1.svc.example.org +short
# 127.0.0.2
# 127.0.0.3
# 127.0.0.7

Variables

name description type required default
project_id Existing project id. string
name Arbitrary string used to name created resources. string "dns-sd-test"
project_create Create project instead ofusing an existing one. bool false
region Compute region used in the example. string "europe-west1"
zone_domain Domain name used for the DNS zone. string "svc.example.org."

Outputs

name description sensitive
gcloud_commands Commands used to SSH to the VMs.
vms VM names.

Test

module "test1" {
  source         = "./fabric/blueprints/cloud-operations/dns-fine-grained-iam"
  name           = "dns-sd-test"
  project_create = true
  project_id     = "test"
}
# tftest modules=9 resources=32