Skip to content

Imgix Source

udx-github edited this page Oct 12, 2026 · 2 revisions

Manages an Imgix source (GCS origin) through the udx/imgix Terraform/OpenTofu provider, so image CDN configuration is real managed state: drift shows in plan output, and existing sources are adopted by ID instead of duplicated.

Use this module when a Rabbit service serves media through Imgix and the source should be declared alongside the rest of the infrastructure config. The origin bucket is provisioned separately (see gcp-storage); this module points Imgix at it.

Supported Features

  • Create and manage a GCS-origin Imgix source (subdomains, bucket, prefix, caching, fallback images, default render params, custom domains, secure URL signing).
  • Adopt an existing source by source_id (declarative import; no CLI import runs).
  • Optional/computed settings omitted from configuration stay unmanaged and mirror the API value; explicit "" / [] / {} clears a field back to the Imgix default.
  • Origin HMAC credentials as GCP Secret Manager references, resolved by R2A before Terraform runs; the secret key is preserved in state (the API never returns it) and rotation is an in-place update.
  • Deployment-aware applies: after any change that triggers an Imgix deploy, the apply waits for the source to reach deployed (or disabled) and fails with the source ID on timeout. Opt out with wait_for_deployed: false.

Prerequisites

  • An Imgix API key with the Sources permission, stored in GCP Secret Manager.
  • A GCS bucket that already exists (e.g. via the gcp-storage module) with a service account allowed to read it, and an HMAC key pair for that service account.
  • The R2A service account needs secretmanager.secretAccessor on the referenced secrets (see k8s-access infra_secrets for the shared-secret grant).

Important Notes

  • The Imgix Management API cannot delete sources (verified: only GET/POST/PATCH are supported). Destroy fails with an explicit error naming the source ID — delete the source in the Imgix dashboard first, then let the run proceed (or remove the state entry). A destroy never disables, orphans, or silently drops a source.
  • Adoption (source_id set): name, deployment.imgix_subdomains, and deployment.gcs_bucket are still required — the provider always manages them. Set them to the source's current values for a clean first plan; any difference plans an in-place update. Leave gcs_access_key / gcs_secret_key null to keep the existing origin credentials.
  • Sparse updates: PATCH sends only managed changes, so settings this module does not model (robots, origin_cache_ttl_days, render_settings, ...) are preserved.
  • annotation is write-only after creation: Imgix regenerates it on any deployment update that omits it, so the configured value is kept in state and resent with every deployment change.
  • A CloudFront (or other CDN) vanity hostname that proxies to the Imgix hostname does not belong in custom_domains; that setting is only for hostnames Imgix itself terminates TLS for.
  • Changing deployment.imgix_subdomains changes the delivery hostnames; anything referencing the old hostname must move too.
  • Source create/update is rate-limited by Imgix to 60/hour; the provider backs off on 429s, but avoid tight churn loops.

Minimal Example

services:
  - name: "Media CDN"
    module: "imgix-source"
    id: "media"
    deployment_order: 165
    configurations:
      imgix_api_key: "projects/<project-id>/secrets/IMGIX_API_KEY"
      name: "example.com media (#{Environment})"
      deployment:
        type: "gcs"
        imgix_subdomains: ["example-media-#{Environment}"]
        gcs_bucket: "media.example.com"
        gcs_access_key: "projects/<project-id>/secrets/IMGIX_GCS_ACCESS_KEY"
        gcs_secret_key: "projects/<project-id>/secrets/IMGIX_GCS_SECRET_KEY"
        default_params:
          auto: "compress,format"

Outputs

Output Description
source_id Imgix source ID, whether created or adopted via source_id.
domains Full delivery hostnames of the source (imgix subdomains plus custom domains), without scheme.
deployment_status Imgix deployment status after the run: deploying, deployed, disabled, or deleted.

secure_url_token is deliberately not exported: R2A persists tofu output -json artifacts verbatim, which include sensitive values in plaintext. When secure_url_enabled is used, read the token from the Imgix dashboard or the Terraform state in the GCS backend.

Full Configuration Schema

The fields below are public module inputs under configurations.

configurations:
  imgix_api_key: ""
  source_id: ""
  name: ""
  enabled: null
  wait_for_deployed: true
  timeouts:
    create: "10m"
    update: "10m"
    delete: "10m"
  deployment:
    type: "gcs"
    imgix_subdomains: []
    gcs_bucket: ""
    gcs_access_key: null   # required on create; null preserves an adopted source's pair ("" would clear it)
    gcs_secret_key: null   # required on create; never returned by the API, preserved in state
    gcs_prefix: null
    custom_domains: null
    default_params: null
    secure_url_enabled: null
    cache_ttl_behavior: null
    cache_ttl_value: null
    cache_ttl_error: null
    crossdomain_xml_enabled: null
    image_error: null
    image_missing: null
    image_error_append_qs: null
    image_missing_append_qs: null
    annotation: null
Field Type Required Description
imgix_api_key string Yes Imgix API key or GCP Secret Manager path (projects/<project-id-or-number>/secrets/<name>). Needs the Sources permission.
source_id string No Existing source ID to adopt via declarative import. When empty, a new source is created; subdomain conflicts fail with the API's error instead of silently adopting.
name string Yes Display name of the source.
enabled boolean No Whether the source serves traffic; omit to preserve the remote value.
wait_for_deployed boolean No Wait for the terminal deployment status after changes (default true).
timeouts object No create/update/delete Go duration strings, 10m default each.
deployment.type string Yes Origin type; only gcs is supported.
deployment.imgix_subdomains list Yes Bare *.imgix.net subdomains; at least one, unique across all Imgix sources.
deployment.gcs_bucket string Yes GCS bucket name, no gs:// prefix. Must exist and be readable by the HMAC key's service account.
deployment.gcs_access_key string On create GCS HMAC access key or GCP secret path. Null preserves an adopted source's key; "" clears.
deployment.gcs_secret_key string On create GCS HMAC secret or GCP secret path. Never returned by the API; preserved in state. Null preserves on adoption; "" clears.
deployment.gcs_prefix string No Origin path prefix; "" clears.
deployment.custom_domains list No Full DNS names Imgix terminates; [] clears.
deployment.default_params map No Render parameters applied to all requests; {} clears.
deployment.secure_url_enabled boolean No Require signed requests; never enabled implicitly.
deployment.cache_ttl_behavior string No respect_origin, override_origin, or enforce_minimum.
deployment.cache_ttl_value number No TTL seconds, 1800–31536000.
deployment.cache_ttl_error number No Error-image TTL seconds, 1–31536000.
deployment.crossdomain_xml_enabled boolean No Serve a cross-domain policy file.
deployment.image_error / image_missing string No Absolute fallback URLs; "" clears.
deployment.image_error_append_qs / image_missing_append_qs boolean No Forward the failed request's query string to the fallback URL.
deployment.annotation string No Deployment comment (write-only after creation); "" clears.

Clone this wiki locally