🏎️
Revisiting driftctl
driftctl[1] について。
個人的には Infrastructure as Code (IaC) を取り入れるのは比較的簡単だと思う。
Terraform に複雑な文法は存在しないし、Terraform の本や記事は大量にある。
一方、IaC を維持することは相応に難しいと思う。なぜか。
console が存在するため、console で変更し、状態の乖離が生まれるから。
改めて driftctl[1:1] について導入を検討する。
tl;dr
- 現在は Google Cloud でも使える。当初は AWS のみだった。
- 意図しない IAM の付与などを監査できる。CI (Continuous Integration) の step として組み込めそう。
-
.driftignore
[2] の管理が重要。
About driftctl
Snyk の OSS。
driftctl is CLI tool that measures infrastructure as code coverage, and tracks infrastructure drift.
driftctl は、コード・カバレッジとしてインフラストラクチャを測定し、インフラストラクチャのドリフトを追跡する CLI ツールである。
Getting stated
IAM
driftctl を実行する(させる)ためには、以下の role が必要。
-
roles/viewer
閲覧者 -
roles/serviceusage.serviceUsageAdmin
Service Usage 管理者
or -
roles/serviceusage.serviceUsageAdmin
Service Usage 管理者 -
roles/cloudasset.viewer
クラウド アセット閲覧者
[3]
Installation- Cloud Shell に install する。
curl -L https://github.com/snyk/driftctl/releases/latest/download/driftctl_linux_amd64 -o driftctl
chmod +x driftctl
sudo mv driftctl /usr/local/bin/
[4]
Usage- scan 対象の project を指定することが重要。
CLOUDSDK_CORE_PROJECT
command
CLOUDSDK_CORE_PROJECT=hoge\
driftctl scan --to gcp+tf --from tfstate+gs://hoge-tfstate/env/dev/default.tfstate
scan
log
gcp_iam_verifier@cloudshell:~ (hoge)$ CLOUDSDK_CORE_PROJECT=hoge\
driftctl scan --to gcp+tf --from tfstate+gs://hoge-tfstate/env/dev/default.tfstate
Scanned states (1)
Found resources not covered by IaC:
google_compute_address:
- projects/hoge/regions/asia-northeast2/addresses/nat-auto-ip-21669046-5-1704943320202150
Address: xx.xx.xx.xx, Name: nat-auto-ip-21669046-5-1704943320202150
google_compute_disk:
- projects/hoge/zones/asia-northeast2-a/disks/gke-cluster-hoge-service-pool-0d194ef2-d6sk
Name: gke-cluster-hoge-service-pool-0d194ef2-d6sk
google_compute_firewall:
- projects/hoge/global/firewalls/default-allow-icmp
- projects/hoge/global/firewalls/default-allow-internal
- projects/hoge/global/firewalls/default-allow-rdp
- projects/hoge/global/firewalls/default-allow-ssh
- projects/hoge/global/firewalls/gke-cluster-hoge-fdda8f5b-all
- projects/hoge/global/firewalls/gke-cluster-hoge-fdda8f5b-exkubelet
- projects/hoge/global/firewalls/gke-cluster-hoge-fdda8f5b-inkubelet
- projects/hoge/global/firewalls/gke-cluster-hoge-fdda8f5b-master
- projects/hoge/global/firewalls/gke-cluster-hoge-fdda8f5b-vms
- projects/hoge/global/firewalls/k8s-7e03882898f0acc7-node-http-hc
- projects/hoge/global/firewalls/k8s-fw-a551924e3cf67427db25e0a105f0fb7a
google_compute_forwarding_rule:
- projects/hoge/regions/asia-northeast2/forwardingRules/a551924e3cf67427db25e0a105f0fb7a
google_compute_global_address:
- projects/hoge/global/addresses/hoge-ip-range
Address: 10.88.80.0, Name: hoge-ip-range
google_compute_instance:
- projects/hoge/zones/asia-northeast2-a/instances/gke-cluster-hoge-service-pool-0d194ef2-d6sk
google_compute_instance_group:
- projects/hoge/zones/asia-northeast2-a/instanceGroups/gke-cluster-hoge-process-pool-7ccd9538-grp
Name: gke-cluster-hoge-process-pool-7ccd9538-grp
- projects/hoge/zones/asia-northeast2-a/instanceGroups/gke-cluster-hoge-service-pool-0d194ef2-grp
Name: gke-cluster-hoge-service-pool-0d194ef2-grp
- projects/hoge/zones/asia-northeast2-a/instanceGroups/gke-cluster-hoge-service-pool-61ee2fe7-grp
Name: gke-cluster-hoge-service-pool-61ee2fe7-grp
google_compute_instance_group_manager:
- projects/hoge/zones/asia-northeast2-a/instanceGroupManagers/gke-cluster-hoge-process-pool-7ccd9538-grp
Name: gke-cluster-hoge-process-pool-7ccd9538-grp
- projects/hoge/zones/asia-northeast2-a/instanceGroupManagers/gke-cluster-hoge-service-pool-0d194ef2-grp
Name: gke-cluster-hoge-service-pool-0d194ef2-grp
- projects/hoge/zones/asia-northeast2-a/instanceGroupManagers/gke-cluster-hoge-service-pool-61ee2fe7-grp
Name: gke-cluster-hoge-service-pool-61ee2fe7-grp
google_compute_network:
- projects/hoge/global/networks/default
google_compute_subnetwork:
- projects/hoge/regions/africa-south1/subnetworks/default
Name: default
- projects/hoge/regions/asia-east1/subnetworks/default
Name: default
- projects/hoge/regions/asia-east2/subnetworks/default
Name: default
- projects/hoge/regions/asia-northeast1/subnetworks/default
Name: default
- projects/hoge/regions/asia-northeast2/subnetworks/default
Name: default
- projects/hoge/regions/asia-northeast3/subnetworks/default
Name: default
- projects/hoge/regions/asia-south1/subnetworks/default
Name: default
- projects/hoge/regions/asia-south2/subnetworks/default
Name: default
- projects/hoge/regions/asia-southeast1/subnetworks/default
Name: default
- projects/hoge/regions/asia-southeast2/subnetworks/default
Name: default
- projects/hoge/regions/australia-southeast1/subnetworks/default
Name: default
- projects/hoge/regions/australia-southeast2/subnetworks/default
Name: default
- projects/hoge/regions/europe-central2/subnetworks/default
Name: default
- projects/hoge/regions/europe-north1/subnetworks/default
Name: default
- projects/hoge/regions/europe-southwest1/subnetworks/default
Name: default
- projects/hoge/regions/europe-west1/subnetworks/default
Name: default
- projects/hoge/regions/europe-west10/subnetworks/default
Name: default
- projects/hoge/regions/europe-west12/subnetworks/default
Name: default
- projects/hoge/regions/europe-west2/subnetworks/default
Name: default
- projects/hoge/regions/europe-west3/subnetworks/default
Name: default
- projects/hoge/regions/europe-west4/subnetworks/default
Name: default
- projects/hoge/regions/europe-west6/subnetworks/default
Name: default
- projects/hoge/regions/europe-west8/subnetworks/default
Name: default
- projects/hoge/regions/europe-west9/subnetworks/default
Name: default
- projects/hoge/regions/me-central1/subnetworks/default
Name: default
- projects/hoge/regions/me-central2/subnetworks/default
Name: default
- projects/hoge/regions/me-west1/subnetworks/default
Name: default
- projects/hoge/regions/northamerica-northeast1/subnetworks/default
Name: default
- projects/hoge/regions/northamerica-northeast2/subnetworks/default
Name: default
- projects/hoge/regions/southamerica-east1/subnetworks/default
Name: default
- projects/hoge/regions/southamerica-west1/subnetworks/default
Name: default
- projects/hoge/regions/us-central1/subnetworks/default
Name: default
- projects/hoge/regions/us-east1/subnetworks/default
Name: default
- projects/hoge/regions/us-east4/subnetworks/default
Name: default
- projects/hoge/regions/us-east5/subnetworks/default
Name: default
- projects/hoge/regions/us-east7/subnetworks/default
Name: default
- projects/hoge/regions/us-south1/subnetworks/default
Name: default
- projects/hoge/regions/us-west1/subnetworks/default
Name: default
- projects/hoge/regions/us-west2/subnetworks/default
Name: default
- projects/hoge/regions/us-west3/subnetworks/default
Name: default
- projects/hoge/regions/us-west4/subnetworks/default
Name: default
- projects/hoge/regions/us-west8/subnetworks/default
Name: default
google_project_iam_member:
- hoge/roles/artifactregistry.reader/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/cloudasset.viewer/group:gcp-hoge-developers@example.jp
- hoge/roles/cloudscheduler.admin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/cloudsql.admin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/cloudsql.client/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/compute.admin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/container.admin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/container.clusterAdmin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/iam.serviceAccountAdmin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/iam.serviceAccountCreator/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/iam.serviceAccountDeleter/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/iam.serviceAccountUser/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/owner/user:danny@example.jp
- hoge/roles/pubsub.admin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/resourcemanager.projectIamAdmin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/run.admin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/secretmanager.admin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/serviceusage.serviceUsageAdmin/group:gcp-hoge-developers@example.jp
- hoge/roles/serviceusage.serviceUsageAdmin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/storage.admin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
- hoge/roles/viewer/group:gcp-hoge-developers@example.jp
- hoge/roles/vpcaccess.admin/serviceAccount:terraform@hoge.iam.gserviceaccount.com
google_sql_database_instance:
- hoge
google_storage_bucket:
- hoge-tfstate
Found 106 resource(s)
- 16% coverage
- 17 resource(s) managed by Terraform
- 89 resource(s) not managed by Terraform
- 0 resource(s) found in a Terraform state but missing on the cloud provider
Scan duration: 4s
Provider version used to scan: . Use --tf-provider-version to use another version.
gcp_iam_verifier@cloudshell:~ (hoge)$
Practice
- 許容するものを
.driftignore
[2:1] に定義する。 -
.driftignore
に存在しない service account/mail account の role が追加された場合 coverage が 100 を切る。それをチェックする。
# driftctl scan --driftignore /path/to/driftignore
CLOUDSDK_CORE_PROJECT=hoge\
driftctl scan --to gcp+tf --from tfstate+gs://hoge-tfstate/env/dev/default.tfstate --driftignore /home/gcp_iam_verifier/.driftignore
log
gcp_iam_verifier@cloudshell:~ (hoge)$ cat .driftignore
*
!google_project_iam_member
*serviceAccount:terraform@hoge.iam.gserviceaccount.com
*yamamoto_daisuke@example.jp
*gcp-hoge-developers@example.jp
gcp_iam_verifier@cloudshell:~ (hoge)$ CLOUDSDK_CORE_PROJECT=hoge driftctl scan --to gcp+tf --from tfstate+gs://hoge-tfstate/env/dev/default.tfstate --driftignore /home/gcp_iam_verifier/.driftignore
Scanned states (1)
Found 14 resource(s)
- 100% coverage
Congrats! Your infrastructure is fully in sync.
Scan duration: 2s
Provider version used to scan: . Use --tf-provider-version to use another version.
gcp_iam_verifier@cloudshell:~ (hoge)$
Discussion