Skip to content

Connecting integrations

Cloudkeel-DD compares desired state against actual state, so most clouds need two integrations working together.

  1. A state source (Terraform Cloud, or raw .tfstate in S3/GCS/Azure Blob) — the desired state.
  2. A cross-check credential (Azure / AWS / GCP, read-only) — the actual live state.

With only the state source, resources are discovered but tagged “no live comparison available”: inventory, not drift. With only the cross-check credential, there’s nothing to compare against. Connect both, per cloud.

Kubernetes is the exception — one kubeconfig integration is self-contained (desired = Helm release record, actual = live API).

Terraform (or raw state) + Azure cross-check. Azure has the deepest field-level verification. Start there, then add more sources.

GuideWhat it connects
Terraform CloudThe recommended first desired-state source
Azure cross-checkLive Azure verification + unmanaged detection
AWS cross-checkLive AWS security-group drift + unmanaged detection
GCP cross-checkLive GCP firewall-rule drift + unmanaged detection
Azure Blob stateRaw .tfstate in Azure Storage, via a narrow SAS
AWS S3 stateRaw .tfstate in S3, via a bucket-scoped IAM user
GCP GCS stateRaw .tfstate in GCS, via a bucket-scoped service account
Kubernetes / HelmDrift on Helm releases — AKS, EKS, GKE, or any cluster

The most common setup mistake is putting a working credential in the wrong slot. They are not interchangeable, and a state reader pasted into a cross-check integration fails with a raw cloud error that does not say so. One row per credential you will create:

IntegrationCredential to createScope it needsThe secret you paste
Azure cross-checkAAD app registration (service principal)Reader on each subscription to verifyClient secret, shown once at creation
AWS cross-checkIAM user or roleRead-only on the described servicesAccess key ID + secret access key
GCP cross-checkService accountViewer / Cloud Asset Inventory read on the projectJSON key file
Azure Blob stateSAS token — no app registration, no RBACRead + List on one containerQuery string from generate-sas
AWS S3 stateIAM user, separate from the cross-check ones3:ListBucket + s3:GetObject on one bucketAccess key ID + secret access key
GCP GCS stateService account, separate from the cross-check onestorage.objectViewer on one bucketJSON key file
Terraform Cloud / EnterpriseUser or team API tokenRead on the workspacesToken from the TFC/TFE UI
Kubernetes / HelmServiceAccount token kubeconfigRead on the namespaces you care aboutThe kubeconfig you assemble

Three things that trip people up:

  • The state credential and the cross-check credential for the same cloud are deliberately different identities. The state one reads one bucket or container; the cross-check one reads live resources across a whole subscription, account, or project. Reusing one for both grants it more than it needs.
  • Azure state needs no app registration at all — it is a plain SAS. If you are creating a service principal for it, you are on the wrong guide.
  • One credential per cloud, for now. A second Azure tenant or AWS account cannot be connected alongside the first; the API rejects it.
  • State source connected, and each discovered .tfstate Enabled.
  • Cross-check credential connected for the same cloud.
  • Cross-check scope enabled — AWS/GCP auto-enable; Azure leaves discovered subscriptions disabled until you opt in.
  • Kubernetes: a static token kubeconfig, not an exec-plugin one.
  • EKS: cluster API access enabled first (access entry).

Hitting a Test connection error? See Troubleshooting — every failure mode mapped to its fix.

Cloudkeel-DD never writes to your cloud. Every guide uses a narrow, read-only credential; the security model and least-privilege reference spell out exactly what each one can and cannot do.