OVH Terraform Provider

repository·master·Indexed 43 days ago

https://github.com/ovh/terraform-provider-ovh

The OVH Terraform Provider enables management of OVHcloud resources using Terraform HCL. It allows users to provision and manage infrastructure such as Vrack, Load Balancers, Domains, Cloud Projects, and Kubernetes clusters with Node Pools through code. The provider supports version >= 2.7.0 and requires OVHcloud API credentials for authentication.

Tokens
277.6K
Snippets
922
Records
1.4K
Agent score
52%

What's inside OVH Terraform Provider

  1. Manage OVHcloud domain zone records with ovh_domain_zone_record

    master

    The ovh_domain_zone_record resource allows you to manage individual DNS records within an OVHcloud domain zone.

    Important Warnings:

    • Avoid mixing Web Console and Terraform: Using the Change in text format feature in the OVHcloud web console will update the record IDs. This causes Terraform to encounter record has been deleted errors because the IDs no longer match. If this happens, you must terraform import the records using their new IDs and stop using the web console for these records.
    • Do not use with ovh_domain_zone_import: You should not use ovh_domain_zone_record and ovh_domain_zone_import together, as the latter manages the entire DNS zone at once and will conflict with individual record management.
    # Add a record to a sub-domain
    resource "ovh_domain_zone_record" "test" {
      zone      = "testdemo.ovh"
      subdomain = "test"
      fieldtype = "A"
      ttl       = 3600
      target    = "0.0.0.0"
    }
  2. Configure placement policies: AFFINITY vs ANTI_AFFINITY

    master

    The policy argument determines how member instances are distributed across hypervisors:

    • ANTI_AFFINITY: Spreads members across distinct hypervisors. Use this for high-availability services to ensure a single host failure does not take down all replicas.
    • AFFINITY: Packs members onto the same hypervisor. Use this for tightly coupled instances that benefit from low-latency communication on a single host.
    resource "ovh_cloud_instance_group" "spread" {
      service_name = "<Public cloud project id>"
      region       = "GRA11"
      name         = "my-anti-affinity-group"
      policy       = "ANTI_AFFINITY"
    }
    
    resource "ovh_cloud_instance_group" "packed" {
      service_name = "<Public cloud project id>"
      region       = "GRA11"
      name         = "my-affinity-group"
      policy       = "AFFINITY"
    }
  3. Manage Cloud-init `user_data` for instances

    master

    The user_data argument allows you to inject Cloud-init configuration at boot. It must be base64-encoded.

    Warning on destructive updates:

    • To update user data: Change the value to a new non-empty string. This reinstalls the instance (rebuilds on current image, wipes root disk), but the instance ID, ports, and IPs survive.
    • To clear user data: Setting the value to "" is a destructive action that triggers a reinstallation and wipes the root disk.
    • To remove user data without wiping: Remove the argument entirely from your Terraform configuration. This prevents the key from being sent in the API PUT request, allowing the instance to keep its existing boot data without a rebuild.

    Example usage with base64encode():

    user_data = base64encode(file("cloud-init.yaml"))
  4. Use conditions in ovh_iam_policy

    master

    The conditions block allows you to restrict permissions based on specific contexts. Conditions can be nested up to 3 levels deep.

    Operators

    • operator (Required): Defines how to combine conditions. Valid values: AND, OR, NOT, or MATCH.
    • MATCH: A terminal operator that compares values. It cannot have sub-conditions.

    Supported Keys in values

    When using the MATCH operator, you can match against:

    • Resource tags: resource.Tag(tag_name) (e.g., resource.Tag(environment))
    • Date/time: date(timezone).WeekDay or date(timezone).WeekDay.In (e.g., date(Europe/Paris).WeekDay.In)
    • Request attributes: request.IP

    Example: IP and Tag Restriction

    resource "ovh_iam_policy" "ip_restricted_prod_access" {
      name        = "ip_restricted_prod_access"
      identities  = [ovh_me_identity_group.my_group.urn]
      resources   = ["urn:v1:eu:resource:vps:*"]
      allow       = ["vps:apiovh:*"]
    
      conditions {
        operator = "MATCH"
        values = {
          "resource.Tag(environment)" = "prod"
          "request.IP"              = "192.72.0.1"
        }
      }
    }
    resource "ovh_iam_policy" "ip_restricted_prod_access" {
      name        = "ip_restricted_prod_access"
      description = "Allow access only from a specific IP to resources tagged prod"
      identities  = [ovh_me_identity_group.my_group.urn]
      resources   = ["urn:v1:eu:resource:vps:*"]
    
      allow = [
        "vps:apiovh:*",
      ]
    
      conditions {
        operator = "MATCH"
        values = {
          "resource.Tag(environment)" = "prod"
          "request.IP"                = "192.72.0.1"
        }
      }
    }
  5. Inspect target_spec in ovh_vrackservices

    master

    The target_spec attribute shows the last requested configuration (target specification). It includes a subnets list (maximum one subnet per vRack Services) with the following details:

    • cidr (String): Private network address (RFC1918) with prefix length /16 to /24.
    • display_name (String): Name following ^[ a-zA-Z0-9-_.]{0,40}$.
    • vlan (Number): Inner VLAN [2 - 4094] or null for untagged.
    • service_endpoints (Attributes List): Target specification for service endpoints, requiring a managed_service_urn that matches the vRack region.
    • service_range (Attributes): A dedicated service subnet (RFC1918) that must be a sub-network of the main subnet, with prefix length /27 to /29.
  6. Inspect current_state in ovh_vrackservices

    master

    The current_state attribute provides details about the active configuration of the vRack Services:

    • product_status (String): The status of the product.
    • region (String): The region of the vRack Services.
    • subnets (Attributes List): A list of subnets currently configured. Each subnet includes:
      • cidr (String): IP range in CIDR format.
      • display_name (String): The subnet's display name.
      • vlan (Number): Unique inner VLAN for segregation.
      • service_endpoints (Attributes List): Managed service endpoints within the subnet.
      • service_range (Attributes): A dedicated smaller subnet for managed service IPs, containing:
        • cidr (String): CIDR for services.
        • remaining_ips (Number): Available IPs.
        • reserved_ips (Number): IPs reserved by OVHcloud.
        • used_ips (Number): IPs assigned to managed services.
  7. Configure Object Lock for storage containers

    master

    Object Lock provides Write-Once-Read-Many (WORM) functionality, preventing objects from being deleted or overwritten for a specified retention period.

    Critical Warnings:

    • Cannot be disabled: Object Lock cannot be disabled once enabled on a bucket.
    • Replacement on change: Removing the object_lock configuration block or changing object_lock.status between disabled and enabled will cause Terraform to destroy and recreate the bucket, resulting in permanent deletion of all objects. Object Lock must be enabled at the time of bucket creation.

    Retention Rules:

    • mode:
      • governance: Users with special permissions can override or remove retention.
      • compliance: No user, including the root user, can override or remove retention until the period expires.
    • period: The retention period in ISO 8601 duration format (e.g., P30D for 30 days, P1W for 1 week). The provider handles normalization (e.g., P7D to P1W) automatically to prevent drift.
    resource "ovh_cloud_project_storage" "storage_with_lock" {
      service_name = "<public cloud project ID>"
      region_name  = "GRA"
      name         = "my-locked-storage"
    
      object_lock = {
        status = "enabled"
        rule = {
          mode   = "governance"
          period = "P30D" # 30 days retention
        }
      }
    }
  8. Manage S3-compatible lifecycle configurations with ovh_cloud_project_storage_object_bucket_lifecycle_configuration

    master

    Use the ovh_cloud_project_storage_object_bucket_lifecycle_configuration resource to manage S3™ compatible lifecycle rules for an OVHcloud Object Storage bucket. These rules allow you to automatically expire objects, transition them to cheaper storage classes, or clean up incomplete multipart uploads based on criteria like age, prefix, tags, or object size.

    Important Behaviors:

    • API Pattern: This resource uses a PUT/DELETE API. There is no separate create vs update endpoint; both actions call PUT. Destroying the resource calls DELETE, which removes the entire lifecycle configuration from the bucket.
    • Replacement: Changing any of the identity attributes (service_name, region_name, or container_name) will require a resource replacement.
    resource "ovh_cloud_project_storage_object_bucket_lifecycle_configuration" "lifecycle" {
      service_name   = "<public cloud project ID>"
      region_name    = "GRA"
      container_name = "my-bucket"
    
      rules = [
        {
          id     = "expire-old-objects"
          status = "enabled"
          expiration = {
            days = 365
          }
        }
      ]
    }
  9. Configure Private Network for Load Balancer

    master

    The network block is required to associate the load balancer with a private network.

    Inside network.private, you must provide a network block containing:

    • id: The private network ID.
    • subnet_id: The subnet ID.

    You can also optionally configure:

    • floating_ip or floating_ip_create: To associate or create a Floating IP.
    • gateway or gateway_create: To associate or create a gateway.
  10. Access the observed state of an instance via current_state

    master

    The current_state attribute provides the actual observed state of the instance as reported by the compute backend. This is useful for verifying the real-time status of an instance, which may differ from the requested specification during transitions.

    Key sub-attributes of current_state include:

    • power_state: The observed administrative power state (e.g., ACTIVE, SHUTOFF, SHELVED).
    • flavor: Details of the observed flavor, including vcpus, ram, disk, swap, and ephemeral sizes.
    • image: Details of the observed boot image, including id, name, size, and status.
    • networks: Observed network interfaces. Each entry contains an addresses list containing FIXED, FLOATING, or ADDITIONAL IP addresses.
    • volumes: Observed block volumes currently attached, including id, name, and size.
    • shares: Observed file storage share attachments (only available via the singular data source, not the list data source). Includes id, access_level, and access_to (the target IP).
    • resource_status: The readiness of the instance in the system (e.g., CREATING, READY, ERROR).
  11. Configure volume encryption (CMK and OMK)

    master

    You can encrypt volumes using either OVH managed keys (OMK) or Customer managed keys (CMK).

    OVH Managed Keys (OMK)

    To use OMK, set encrypted = true within the encryption block and omit the kms block.

    Customer Managed Keys (CMK)

    To use CMK, provide the kms block containing the domain_id and service_key_id. Note that CMK is only available in supported 3AZ regions.

    Warning: Changing the encryption configuration recreates the resource.

    # Encrypted volume with a customer managed key (CMK)
    resource "ovh_cloud_project_volume" "encrypted_volume" {
       region_name  = "xxx"
       service_name = "yyyyy"
       description  = "Terraform encrypted volume"
       name         = "encryptedVolume"
       size         = 15
       type         = "classic"
    
       encryption = {
         encrypted = true
         kms = {
           domain_id      = "<okms domain id>"
           service_key_id = "<okms service key id>"
         }
       }
    }
    
    # Encrypted volume with OVH managed keys (OMK)
    resource "ovh_cloud_project_volume" "encrypted_volume_omk" {
       region_name  = "xxx"
       service_name = "yyyyy"
       name         = "encryptedVolume"
       size         = 15
       type         = "classic"
    
       encryption = {
         encrypted = true
       }
    }
  12. Reset a database user password using `password_reset`

    master

    To trigger a password reset for an existing user, update the password_reset attribute with an arbitrary string. After running terraform apply, you must run terraform refresh to update your Terraform state and outputs with the newly generated password.

    Recommended patterns for password_reset:

    1. Datetime: Use a timestamp to keep a trace of the last reset.
    2. MD5 Hash: Use an MD5 hash of other variables to automatically trigger a reset whenever those variables change.

    Example using a datetime:

    resource "ovh_cloud_project_database_user" "user_datetime" {
      service_name    = data.ovh_cloud_project_database.db.service_name
      engine          = data.ovh_cloud_project_database.db.engine
      cluster_id      = data.ovh_cloud_project_database.db.id
      name            = "alice"
      password_reset  = "2024-01-02T11:00:00Z"
    }