Repository: kinvolk/lokomotive
Pull request #1132 (2020-10-28 06:52:37)

Add `require_volume_annotation` for restic plugin
This PR is based on top of #1131 and would need to be merged first.

Adds a new field `require_volume_annotation` that was introduced in Velero v1.5.2.

If enabled the user will  have to manually add annotations to the pod when taking backups.

Default is `false`, i.e volumes will be backed up without the need for annotation.

invidian: I just noticed this PR includes commits from #1131, sorry that I put all review comments here. It's good to mention such things in PR description :) 
invidian: There are conflicts which needs to be resolved.
ipochi: @invidian yes, I found a bug in the existing code and resolving that.
ipochi: @invidian There is an opt-out feature in Velero which should be added as annotation if volume is not be backed up by restic by default.

Should we flip the default value for `require_volume_annotation` to `false` i.e opt-out strategy where volume will not be considered for back up if the resource has the following annotation `backup.velero.io/backup-volumes-excludes` ?


invidian: >Should we flip the default value for require_volume_annotation to false i.e opt-out strategy where volume will not be considered for back up if the resource has the following annotation backup.velero.io/backup-volumes-excludes ?

Sounds good :+1: If we have a place for it, we could mention it in our documentation for Velero component.

Patch:
diff --git a/docs/configuration-reference/components/velero.md b/docs/configuration-reference/components/velero.md
index 4a158f78..a913fa17 100644
--- a/docs/configuration-reference/components/velero.md
+++ b/docs/configuration-reference/components/velero.md
@@ -81,6 +81,8 @@ component "velero" {
   # restic {
   #   credentials = file("cloud-credentials-file")
   #
+  #   require_volume_annotation = true
+  #
   #   backup_storage_location {
   #     provider = "aws"
   #     bucket   = "my-bucket"
@@ -102,50 +104,50 @@ component "velero" {
 
 Table of all the arguments accepted by the component.
 
-| Argument                                             | Description                                                                                                                 | Default                                           | Type   | Required |
-|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------|--------|----------|
-| `namespace`                                          | Namespace to install Velero.                                                                                                | "velero"                                          | string | false    |
-| `provider`                                           | Provider sets which provider block to use for the configuration. Supported values are: `azure`, `openebs` and `restic`.     | -                                                 | string | true     |
-| `metrics`                                            | Configure Prometheus to scrape Velero metrics. Needs the [Prometheus Operator component](../prometheus-operator) installed. | -                                                 | object | false    |
-| `metrics.enabled`                                    | Adds Prometheus annotations to Velero deployment if enabled.                                                                | false                                             | bool   | false    |
-| `metrics.service_monitor`                            | Adds ServiceMonitor resource for Prometheus. Requires `metrics.enabled` as true.                                            | false                                             | bool   | false    |
-| `azure`                                              | Configure Azure provider for Velero.                                                                                        | -                                                 | object | false    |
-| `azure.subscription_id`                              | Azure Subscription ID where client application is created. Can be obtained with `az account list`.                          | -                                                 | string | true     |
-| `azure.tenant_id`                                    | Azure Tenant ID where your subscription is created. Can be obtained with `az account list`.                                 | -                                                 | string | true     |
-| `azure.client_id`                                    | Azure Application Client ID to perform Azure operations.                                                                    | -                                                 | string | true     |
-| `azure.client_secret`                                | Azure Application Client secret.                                                                                            | -                                                 | string | true     |
-| `azure.resource_group`                               | Azure resource group, where PVC Disks are created. If this argument is wrong, Velero will fail to create PVC snapshots.     | -                                                 | string | true     |
-| `azure.backup_storage_location`                      | Configure backup storage location and metadata.                                                                             | -                                                 | object | true     |
-| `azure.backup_storage_location.resource_group`       | Name of the resource group containing the storage account for this backup storage location.                                 | -                                                 | string | true     |
-| `azure.backup_storage_location.storage_account`      | Name of the storage account for this backup storage location.                                                               | -                                                 | string | true     |
-| `azure.backup_storage_location.bucket`               | Name of the storage container to store backups.                                                                             | -                                                 | string | true     |
-| `azure.volume_snapshot_location`                     | Configure PVC snapshot location.                                                                                            | -                                                 | object | false    |
-| `azure.volume_snapshot_location.resource_group`      | Azure Resource Group where snapshots will be stored.                                                                        | Stored in the same resource group as the cluster. | string | false    |
-| `azure.volume_snapshot_location.api_timeout`         | Azure API timeout.                                                                                                          | "10m"                                             | string | false    |
-| `openebs`                                            | Configure OpenEBS provider for Velero.                                                                                      | -                                                 | object | false    |
-| `openebs.credentials`                                | Content of cloud provider credentials.                                                                                      | -                                                 | string | true     |
-| `openebs.provider`                                   | Cloud provider to use for backup and snapshot storage. Supported values are `gcp` and `aws`.                                | -                                                 | string | false    |
-| `openebs.backup_storage_location`                    | Configure backup storage location.                                                                                          | -                                                 | object | true     |
-| `openebs.backup_storage_location.region`             | Cloud provider region for storing backups.                                                                                  | -                                                 | string | true     |
-| `openebs.backup_storage_location.bucket`             | Cloud storage bucket name for storing backups.                                                                              | -                                                 | string | true     |
-| `openebs.backup_storage_location.provider`           | Cloud provider name for storing backups. Overrides `openebs.provider` field for backup storage.                             | -                                                 | string | false    |
-| `openebs.backup_storage_location.name`               | Name for backup location object on the cluster.                                                                             | -                                                 | string | false    |
-| `openebs.volume_snapshot_location`                   | Configure volume snapshot location.                                                                                         | -                                                 | object | true     |
-| `openebs.volume_snapshot_location.bucket`            | Cloud storage bucket name for storing volume snapshots.                                                                     | -                                                 | string | true     |
-| `openebs.volume_snapshot_location.region`            | Cloud provider region for storing snapshots.                                                                                |                                                   | string | true     |
-| `openebs.volume_snapshot_location.provider`          | Cloud provider name for storing snapshots. Overrides `openebs.provider` field for backup storage.                           | -                                                 | string | false    |
-| `openebs.volume_snapshot_location.name`              | Name for snapshot location object on the cluster.                                                                           | -                                                 | string | false    |
-| `openebs.volume_snapshot_location.prefix`            | Prefix for snapshot names.                                                                                                  | -                                                 | string | false    |
-| `openebs.volume_snapshot_location.local`             | If `true`, backups won't be copied to cloud storage.                                                                        | false                                             | bool   | false    |
-| `openebs.volume_snapshot_location.openebs_namespace` | Name of the namespace where OpenEBS runs.                                                                                   | -                                                 | string | true     |
-| `openebs.volume_snapshot_location.s3_url`            | S3 API URL.                                                                                                                 | -                                                 | string | false    |
-| `restic`                                             | Configure Restic provider for Velero.                                                                                       | -                                                 | object | false    |
-| `restic.credentials`                                 | Content of cloud provider credentials.                                                                                      | -                                                 | string | true     |
-| `restic.backup_storage_location.provider`            | Cloud provider name for storing backups.                                                                                    | -                                                 | string | true     |
-| `restic.backup_storage_location.bucket`              | Cloud storage bucket name for storing backups.                                                                              | -                                                 | string | true     |
-| `restic.backup_storage_location.name`                | Name for backup location object on the cluster.                                                                             | "default"                                         | string | false    |
-| `restic.backup_storage_location.region`              | Cloud provider region for storing snapshots. Required if `restic.backup_storage_location.provider = aws`.                   | -                                                 | string | false    |
-
+| Argument                                             | Description                                                                                                                                                                          | Default                                           | Type   | Required |
+|------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------|--------|----------|
+| `namespace`                                          | Namespace to install Velero.                                                                                                                                                         | "velero"                                          | string | false    |
+| `provider`                                           | Provider sets which provider block to use for the configuration. Supported values are: `azure`, `openebs` and `restic`.                                                              | -                                                 | string | true     |
+| `metrics`                                            | Configure Prometheus to scrape Velero metrics. Needs the [Prometheus Operator component](../prometheus-operator) installed.                                                          | -                                                 | object | false    |
+| `metrics.enabled`                                    | Adds Prometheus annotations to Velero deployment if enabled.                                                                                                                         | false                                             | bool   | false    |
+| `metrics.service_monitor`                            | Adds ServiceMonitor resource for Prometheus. Requires `metrics.enabled` as true.                                                                                                     | false                                             | bool   | false    |
+| `azure`                                              | Configure Azure provider for Velero.                                                                                                                                                 | -                                                 | object | false    |
+| `azure.subscription_id`                              | Azure Subscription ID where client application is created. Can be obtained with `az account list`.                                                                                   | -                                                 | string | true     |
+| `azure.tenant_id`                                    | Azure Tenant ID where your subscription is created. Can be obtained with `az account list`.                                                                                          | -                                                 | string | true     |
+| `azure.client_id`                                    | Azure Application Client ID to perform Azure operations.                                                                                                                             | -                                                 | string | true     |
+| `azure.client_secret`                                | Azure Application Client secret.                                                                                                                                                     | -                                                 | string | true     |
+| `azure.resource_group`                               | Azure resource group, where PVC Disks are created. If this argument is wrong, Velero will fail to create PVC snapshots.                                                              | -                                                 | string | true     |
+| `azure.backup_storage_location`                      | Configure backup storage location and metadata.                                                                                                                                      | -                                                 | object | true     |
+| `azure.backup_storage_location.resource_group`       | Name of the resource group containing the storage account for this backup storage location.                                                                                          | -                                                 | string | true     |
+| `azure.backup_storage_location.storage_account`      | Name of the storage account for this backup storage location.                                                                                                                        | -                                                 | string | true     |
+| `azure.backup_storage_location.bucket`               | Name of the storage container to store backups.                                                                                                                                      | -                                                 | string | true     |
+| `azure.volume_snapshot_location`                     | Configure PVC snapshot location.                                                                                                                                                     | -                                                 | object | false    |
+| `azure.volume_snapshot_location.resource_group`      | Azure Resource Group where snapshots will be stored.                                                                                                                                 | Stored in the same resource group as the cluster. | string | false    |
+| `azure.volume_snapshot_location.api_timeout`         | Azure API timeout.                                                                                                                                                                   | "10m"                                             | string | false    |
+| `openebs`                                            | Configure OpenEBS provider for Velero.                                                                                                                                               | -                                                 | object | false    |
+| `openebs.credentials`                                | Content of cloud provider credentials.                                                                                                                                               | -                                                 | string | true     |
+| `openebs.provider`                                   | Cloud provider to use for backup and snapshot storage. Supported values are `gcp` and `aws`.                                                                                         | -                                                 | string | false    |
+| `openebs.backup_storage_location`                    | Configure backup storage location.                                                                                                                                                   | -                                                 | object | true     |
+| `openebs.backup_storage_location.region`             | Cloud provider region for storing backups.                                                                                                                                           | -                                                 | string | true     |
+| `openebs.backup_storage_location.bucket`             | Cloud storage bucket name for storing backups.                                                                                                                                       | -                                                 | string | true     |
+| `openebs.backup_storage_location.provider`           | Cloud provider name for storing backups. Overrides `openebs.provider` field for backup storage.                                                                                      | -                                                 | string | false    |
+| `openebs.backup_storage_location.name`               | Name for backup location object on the cluster.                                                                                                                                      | -                                                 | string | false    |
+| `openebs.volume_snapshot_location`                   | Configure volume snapshot location.                                                                                                                                                  | -                                                 | object | true     |
+| `openebs.volume_snapshot_location.bucket`            | Cloud storage bucket name for storing volume snapshots.                                                                                                                              | -                                                 | string | true     |
+| `openebs.volume_snapshot_location.region`            | Cloud provider region for storing snapshots.                                                                                                                                         |                                                   | string | true     |
+| `openebs.volume_snapshot_location.provider`          | Cloud provider name for storing snapshots. Overrides `openebs.provider` field for backup storage.                                                                                    | -                                                 | string | false    |
+| `openebs.volume_snapshot_location.name`              | Name for snapshot location object on the cluster.                                                                                                                                    | -                                                 | string | false    |
+| `openebs.volume_snapshot_location.prefix`            | Prefix for snapshot names.                                                                                                                                                           | -                                                 | string | false    |
+| `openebs.volume_snapshot_location.local`             | If `true`, backups won't be copied to cloud storage.                                                                                                                                 | false                                             | bool   | false    |
+| `openebs.volume_snapshot_location.openebs_namespace` | Name of the namespace where OpenEBS runs.                                                                                                                                            | -                                                 | string | true     |
+| `openebs.volume_snapshot_location.s3_url`            | S3 API URL.                                                                                                                                                                          | -                                                 | string | false    |
+| `restic`                                             | Configure Restic provider for Velero.                                                                                                                                                | -                                                 | object | false    |
+| `restic.credentials`                                 | Content of cloud provider credentials.                                                                                                                                               | -                                                 | string | true     |
+| `restic.require_volume_annotation`                   | Backup all pod volumes without having to apply annotation on the pod when using restic. To exclude volumes add the annotation `backup.velero.io/backup-volumes-excludes` on the pod. | false                                             | bool   | false
+| `restic.backup_storage_location.provider`            | Cloud provider name for storing backups.                                                                                                                                             | -                                                 | string | false    |
+| `restic.backup_storage_location.bucket`              | Cloud storage bucket name for storing backups.                                                                                                                                       | -                                                 | string | true     |
+| `restic.backup_storage_location.name`                | Name for backup location object on the cluster.                                                                                                                                      | "default"                                         | string | false    |
+| `restic.backup_storage_location.region`              | Cloud provider region for storing snapshots. Required if `restic.backup_storage_location.provider = aws`.                                                                            | -                                                 | string | false    |
 ## Applying
 
 To apply the Velero component:
diff --git a/docs/configuration-reference/platforms/packet.md b/docs/configuration-reference/platforms/packet.md
index 716511e4..f755cfa3 100644
--- a/docs/configuration-reference/platforms/packet.md
+++ b/docs/configuration-reference/platforms/packet.md
@@ -192,62 +192,63 @@ node_type = var.custom_default_worker_type
 
 ## Attribute reference
 
-| Argument                              | Description                                                                                                                                                                                                                                                                                                                        | Default         | Type         | Required |
-|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-:-:-------------|-:-:----------|-:-:------|
-| `auth_token`                          | Packet Auth token. Use the `PACKET_AUTH_TOKEN` environment variable instead.                                                                                                                                                                                                                                                       | -               | string       | false    |
-| `asset_dir`                           | Location where Lokomotive stores cluster assets.                                                                                                                                                                                                                                                                                   | -               | string       | true     |
-| `cluster_name`                        | Name of the cluster.                                                                                                                                                                                                                                                                                                               | -               | string       | true     |
-| `tags`                                | List of tags that will be propagated to master nodes.                                                                                                                                                                                                                                                                              | -               | map(string)  | false    |
-| `controller_count`                    | Number of controller nodes.                                                                                                                                                                                                                                                                                                        | 1               | number       | false    |
-| `controller_type`                     | Packet instance type for controllers. Changing this field on existing cluster will be ignored. To actually apply it, cluster needs to be destroyed and re-created.                                                                                                                                                                 | "c3.small.x86"  | string       | false    |
-| `controller_clc_snippets`             | Controller Flatcar Container Linux Config snippets.                                                                                                                                                                                                                                                                                | []              | list(string) | false    |
-| `dns`                                 | DNS configuration block.                                                                                                                                                                                                                                                                                                           | -               | object       | true     |
-| `dns.zone`                            | A DNS zone to use for the cluster. The following format is used for cluster-related DNS records: `<record>.<cluster_name>.<dns_zone>`                                                                                                                                                                                              | -               | string       | true     |
-| `dns.provider`                        | DNS provider to use for the cluster. Valid values: `cloudflare`, `route53`, `manual`.                                                                                                                                                                                                                                              | -               | string       | true     |
-| `oidc`                                | OIDC configuration block.                                                                                                                                                                                                                                                                                                          | -               | object       | false    |
-| `oidc.issuer_url`                     | URL of the provider which allows the API server to discover public signing keys. Only URLs which use the https:// scheme are accepted.                                                                                                                                                                                             | -               | string       | false    |
-| `oidc.client_id`                      | A client id that all tokens must be issued for.                                                                                                                                                                                                                                                                                    | "clusterauth"   | string       | false    |
-| `oidc.username_claim`                 | JWT claim to use as the user name.                                                                                                                                                                                                                                                                                                 | "email"         | string       | false    |
-| `oidc.groups_claim`                   | JWT claim to use as the user’s group.                                                                                                                                                                                                                                                                                              | "groups"        | string       | false    |
-| `facility`                            | Packet facility to use for deploying the cluster.                                                                                                                                                                                                                                                                                  | -               | string       | false    |
-| `project_id`                          | Packet project ID.                                                                                                                                                                                                                                                                                                                 | -               | string       | true     |
-| `ssh_pubkeys`                         | List of SSH public keys for user `core`. Each element must be specified in a valid OpenSSH public key format, as defined in RFC 4253 Section 6.6, e.g. "ssh-rsa AAAAB3N...".                                                                                                                                                       | -               | list(string) | true     |
-| `os_arch`                             | Flatcar Container Linux architecture to install (amd64, arm64).                                                                                                                                                                                                                                                                    | "amd64"         | string       | false    |
-| `os_channel`                          | Flatcar Container Linux channel to install from (stable, beta, alpha, edge).                                                                                                                                                                                                                                                       | "stable"        | string       | false    |
-| `os_version`                          | Flatcar Container Linux version to install. Version such as "2303.3.1" or "current".                                                                                                                                                                                                                                               | "current"       | string       | false    |
-| `ipxe_script_url`                     | Boot via iPXE. Required for arm64.                                                                                                                                                                                                                                                                                                 | -               | string       | false    |
-| `management_cidrs`                    | List of IPv4 CIDRs authorized to access or manage the cluster. Example ["0.0.0.0/0"] to allow all.                                                                                                                                                                                                                                 | -               | list(string) | true     |
-| `node_private_cidr`                   | Private IPv4 CIDR of the nodes used to allow inter-node traffic. Example "10.0.0.0/8"                                                                                                                                                                                                                                              | -               | string       | true     |
-| `enable_aggregation`                  | Enable the Kubernetes Aggregation Layer.                                                                                                                                                                                                                                                                                           | true            | bool         | false    |
-| `enable_tls_bootstrap`                | Enable TLS bootstraping for Kubelet.                                                                                                                                                                                                                                                                                               | true            | bool         | false    |
-| `encrypt_pod_traffic`                 | Enable in-cluster pod traffic encryption. If true `network_mtu` is reduced by 60 to make room for the encryption header.                                                                                                                                                                                                           | false           | bool         | false    |
-| `ignore_x509_cn_check`                | Ignore check of common name in x509 certificates. If any application is built pre golang 1.15 then API server rejects x509 from such application, enable this to get around apiserver.                                                                                                                                             | false           | bool         | false    |
-| `network_mtu`                         | Physical Network MTU.                                                                                                                                                                                                                                                                                                              | 1500            | number       | false    |
-| `pod_cidr`                            | CIDR IPv4 range to assign Kubernetes pods.                                                                                                                                                                                                                                                                                         | "10.2.0.0/16"   | string       | false    |
-| `service_cidr`                        | CIDR IPv4 range to assign Kubernetes services.                                                                                                                                                                                                                                                                                     | "10.3.0.0/16"   | string       | false    |
-| `cluster_domain_suffix`               | Cluster's DNS domain.                                                                                                                                                                                                                                                                                                              | "cluster.local" | string       | false    |
-| `enable_reporting`                    | Enables usage or analytics reporting to upstream.                                                                                                                                                                                                                                                                                  | false           | bool         | false    |
-| `reservation_ids`                     | Block with Packet hardware reservation IDs for controller nodes. Each key must have the format `controller-${index}` and the value is the reservation UUID. Can't be combined with `reservation_ids_default`. Key indexes must be sequential and start from 0. Example: `reservation_ids = { controller-0 = "<reservation_id>" }`. | -               | map(string)  | false    |
-| `reservation_ids_default`             | Default reservation ID for controllers. The value`next-available` will choose any reservation that matches the pool's device type and facility. Can't be combined with `reservation_ids`                                                                                                                                           | -               | string       | false    |
-| `certs_validity_period_hours`         | Validity of all the certificates in hours.                                                                                                                                                                                                                                                                                         | 8760            | number       | false    |
-| `worker_pool`                         | Configuration block for worker pools. There can be more than one.                                                                                                                                                                                                                                                                  | -               | list(object) | true     |
-| `worker_pool.count`                   | Number of workers in the worker pool. Can be changed afterwards to add or delete workers.                                                                                                                                                                                                                                          | 1               | number       | true     |
-| `worker_pool.clc_snippets`            | Flatcar Container Linux Config snippets for nodes in the worker pool.                                                                                                                                                                                                                                                              | []              | list(string) | false    |
-| `worker_pool.tags`                    | List of tags that will be propagated to nodes in the worker pool.                                                                                                                                                                                                                                                                  | -               | map(string)  | false    |
-| `worker_pool.disable_bgp`             | Disable BGP on nodes. Nodes won't be able to connect to Packet BGP peers.                                                                                                                                                                                                                                                          | false           | bool         | false    |
-| `worker_pool.ipxe_script_url`         | Boot via iPXE. Required for arm64.                                                                                                                                                                                                                                                                                                 | -               | string       | false    |
-| `worker_pool.os_arch`                 | Flatcar Container Linux architecture to install (amd64, arm64).                                                                                                                                                                                                                                                                    | "amd64"         | string       | false    |
-| `worker_pool.os_channel`              | Flatcar Container Linux channel to install from (stable, beta, alpha, edge).                                                                                                                                                                                                                                                       | "stable"        | string       | false    |
-| `worker_pool.os_version`              | Flatcar Container Linux version to install. Version such as "2303.3.1" or "current".                                                                                                                                                                                                                                               | "current"       | string       | false    |
-| `worker_pool.node_type`               | Packet instance type for worker nodes.                                                                                                                                                                                                                                                                                             | "c3.small.x86"  | string       | false    |
-| `worker_pool.labels`                  | Map of extra Kubernetes Node labels for worker nodes.                                                                                                                                                                                                                                                                              | -               | map(string)  | false    |
-| `worker_pool.taints`                  | Map of Taints to assign to worker nodes.                                                                                                                                                                                                                                                                                           | -               | map(string)  | false    |
-| `worker_pool.reservation_ids`         | Block with Packet hardware reservation IDs for worker nodes. Each key must have the format `worker-${index}` and the value is the reservation UUID. Can't be combined with `reservation_ids_default`. Key indexes must be sequential and start from 0. Example: `reservation_ids = { worker-0 = "<reservation_id>" }`.             | -               | map(string)  | false    |
-| `worker_pool.reservation_ids_default` | Default reservation ID for workers. The value`next-available` will choose any reservation that matches the pool's device type and facility. Can't be combined with `reservation_ids`.                                                                                                                                              | -               | string       | false    |
-| `worker_pool.setup_raid`              | Attempt to create a RAID 0 from extra disks to be used for persistent container storage. Can't be used with `setup_raid_hdd` nor `setup_raid_sdd`.                                                                                                                                                                                 | false           | bool         | false    |
-| `worker_pool.setup_raid_hdd`          | Attempt to create a RAID 0 from extra Hard Disk drives only, to be used for persistent container storage. Can't be used with `setup_raid` nor `setup_raid_sdd`.                                                                                                                                                                    | false           | bool         | false    |
-| `worker_pool.setup_raid_ssd`          | Attempt to create a RAID 0 from extra Solid State Drives only, to be used for persistent container storage.  Can't be used with `setup_raid` nor `setup_raid_hdd`.                                                                                                                                                                 | false           | bool         | false    |
-| `worker_pool.setup_raid_ssd_fs`       | When set to `true` file system will be created on SSD RAID device and will be mounted on `/mnt/node-local-ssd-storage`. To use the raw device set it to `false`.                                                                                                                                                                   | false           | bool         | false    |
+| Argument                              | Description                                                                                                                                                                                                                                                                       |     Default     |     Type     | Required |
+|---------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------:|:------------:|:--------:|
+| `auth_token`                          | Packet Auth token. Use the `PACKET_AUTH_TOKEN` environment variable instead.                                                                                                                                                                                                      |        -        |    string    |  false   |
+| `asset_dir`                           | Location where Lokomotive stores cluster assets.                                                                                                                                                                                                                                  |        -        |    string    |   true   |
+| `cluster_name`                        | Name of the cluster.                                                                                                                                                                                                                                                              |        -        |    string    |   true   |
+| `tags`                                | List of tags that will be propagated to master nodes.                                                                                                                                                                                                                             |        -        | map(string)  |  false   |
+| `controller_count`                    | Number of controller nodes.                                                                                                                                                                                                                                                       |        1        |    number    |  false   |
+| `controller_type`                     | Packet instance type for controllers. Changing this field on existing cluster will be ignored. To actually apply it, cluster needs to be destroyed and re-created.                                                                                                                | "c3.small.x86"  |    string    |  false   |
+| `controller_clc_snippets`             | Controller Flatcar Container Linux Config snippets.                                                                                                                                                                                                                               |       []        | list(string) |  false   |
+| `dns`                                 | DNS configuration block.                                                                                                                                                                                                                                                          |        -        |    object    |   true   |
+| `dns.zone`                            | A DNS zone to use for the cluster. The following format is used for cluster-related DNS records: `<record>.<cluster_name>.<dns_zone>`                                                                                                                                             |        -        |    string    |   true   |
+| `dns.provider`                        | DNS provider to use for the cluster. Valid values: `cloudflare`, `route53`, `manual`.                                                                                                                                                                                             |        -        |    string    |   true   |
+| `oidc`                                | OIDC configuration block.                                                                                                                                                                                                                                                         |        -        |    object    |  false   |
+| `oidc.issuer_url`                     | URL of the provider which allows the API server to discover public signing keys. Only URLs which use the https:// scheme are accepted.                                                                                                                                            |        -        |    string    |  false   |
+| `oidc.client_id`                      | A client id that all tokens must be issued for.                                                                                                                                                                                                                                   |  "clusterauth"  |    string    |  false   |
+| `oidc.username_claim`                 | JWT claim to use as the user name.                                                                                                                                                                                                                                                |     "email"     |    string    |  false   |
+| `oidc.groups_claim`                   | JWT claim to use as the user’s group.                                                                                                                                                                                                                                             |    "groups"     |    string    |  false   |
+| `facility`                            | Packet facility to use for deploying the cluster.                                                                                                                                                                                                                                 |        -        |    string    |  false   |
+| `project_id`                          | Packet project ID.                                                                                                                                                                                                                                                                |        -        |    string    |   true   |
+| `ssh_pubkeys`                         | List of SSH public keys for user `core`. Each element must be specified in a valid OpenSSH public key format, as defined in RFC 4253 Section 6.6, e.g. "ssh-rsa AAAAB3N...".                                                                                                      |        -        | list(string) |   true   |
+| `os_arch`                             | Flatcar Container Linux architecture to install (amd64, arm64).                                                                                                                                                                                                                   |     "amd64"     |    string    |  false   |
+| `os_channel`                          | Flatcar Container Linux channel to install from (stable, beta, alpha, edge).                                                                                                                                                                                                      |    "stable"     |    string    |  false   |
+| `os_version`                          | Flatcar Container Linux version to install. Version such as "2303.3.1" or "current".                                                                                                                                                                                              |    "current"    |    string    |  false   |
+| `ipxe_script_url`                     | Boot via iPXE. Required for arm64.                                                                                                                                                                                                                                                |        -        |    string    |  false   |
+| `management_cidrs`                    | List of IPv4 CIDRs authorized to access or manage the cluster. Example ["0.0.0.0/0"] to allow all.                                                                                                                                                                                |        -        | list(string) |   true   |
+| `node_private_cidr`                   | Private IPv4 CIDR of the nodes used to allow inter-node traffic. Example "10.0.0.0/8"                                                                                                                                                                                             |        -        |    string    |   true   |
+| `enable_aggregation`                  | Enable the Kubernetes Aggregation Layer.                                                                                                                                                                                                                                          |      true       |     bool     |  false   |
+| `enable_tls_bootstrap`                | Enable TLS bootstraping for Kubelet.                                                                                                                                                                                                                                              |      true       |     bool     |  false   |
+| `encrypt_pod_traffic`                 | Enable in-cluster pod traffic encryption. If true `network_mtu` is reduced by 60 to make room for the encryption header.                                                                                                                                                          |      false      |     bool     |  false   |
+| `ignore_x509_cn_check`                | Ignore check of common name in x509 certificates. If any application is built pre golang 1.15 then API server rejects x509 from such application, enable this to get around apiserver.                                                                                            |      false      |     bool     |  false   |
+| `network_mtu`                         | Physical Network MTU.                                                                                                                                                                                                                                                             |      1500       |    number    |  false   |
+| `pod_cidr`                            | CIDR IPv4 range to assign Kubernetes pods.                                                                                                                                                                                                                                        |  "10.2.0.0/16"  |    string    |  false   |
+| `service_cidr`                        | CIDR IPv4 range to assign Kubernetes services.                                                                                                                                                                                                                                    |  "10.3.0.0/16"  |    string    |  false   |
+| `cluster_domain_suffix`               | Cluster's DNS domain.                                                                                                                                                                                                                                                             | "cluster.local" |    string    |  false   |
+| `enable_reporting`                    | Enables usage or analytics reporting to upstream.                                                                                                                                                                                                                                 |      false      |     bool     |  false   |
+| `reservation_ids`                     | Block with Packet hardware reservation IDs for controller nodes. Each key must have the format `controller-${index}` and the value is the reservation UUID. Can't be combined with `reservation_ids_default`. Example: `reservation_ids = { controller-0 = "<reservation_id>" }`. |        -        | map(string)  |  false   |
+| `reservation_ids_default`             | Default reservation ID for controllers. The value`next-available` will choose any reservation that matches the pool's device type and facility. Can't be combined with `reservation_ids`                                                                                          |        -        |    string    |  false   |
+| `certs_validity_period_hours`         | Validity of all the certificates in hours.                                                                                                                                                                                                                                        |      8760       |    number    |  false   |
+| `worker_pool`                         | Configuration block for worker pools. There can be more than one.                                                                                                                                                                                                                 |        -        | list(object) |   true   |
+| `worker_pool.count`                   | Number of workers in the worker pool. Can be changed afterwards to add or delete workers.                                                                                                                                                                                         |        1        |    number    |   true   |
+| `worker_pool.clc_snippets`            | Flatcar Container Linux Config snippets for nodes in the worker pool.                                                                                                                                                                                                             |       []        | list(string) |  false   |
+| `worker_pool.tags`                    | List of tags that will be propagated to nodes in the worker pool.                                                                                                                                                                                                                 |        -        | map(string)  |  false   |
+| `worker_pool.disable_bgp`             | Disable BGP on nodes. Nodes won't be able to connect to Packet BGP peers.                                                                                                                                                                                                         |      false      |     bool     |  false   |
+| `worker_pool.ipxe_script_url`         | Boot via iPXE. Required for arm64.                                                                                                                                                                                                                                                |        -        |    string    |  false   |
+| `worker_pool.os_arch`                 | Flatcar Container Linux architecture to install (amd64, arm64).                                                                                                                                                                                                                   |     "amd64"     |    string    |  false   |
+| `worker_pool.os_channel`              | Flatcar Container Linux channel to install from (stable, beta, alpha, edge).                                                                                                                                                                                                      |    "stable"     |    string    |  false   |
+| `worker_pool.os_version`              | Flatcar Container Linux version to install. Version such as "2303.3.1" or "current".                                                                                                                                                                                              |    "current"    |    string    |  false   |
+| `worker_pool.node_type`               | Packet instance type for worker nodes.                                                                                                                                                                                                                                            | "c3.small.x86"  |    string    |  false   |
+| `worker_pool.labels`                  | Map of extra Kubernetes Node labels for worker nodes.                                                                                                                                                                                                                             |        -        | map(string)  |  false   |
+| `worker_pool.taints`                  | Map of Taints to assign to worker nodes.                                                                                                                                                                                                                                          |        -        | map(string)  |  false   |
+| `worker_pool.reservation_ids`         | Block with Packet hardware reservation IDs for worker nodes. Each key must have the format `worker-${index}` and the value is the reservation UUID. Can't be combined with `reservation_ids_default`. Example: `reservation_ids = { worker-0 = "<reservation_id>" }`.             |        -        | map(string)  |  false   |
+| `worker_pool.reservation_ids_default` | Default reservation ID for workers. The value`next-available` will choose any reservation that matches the pool's device type and facility. Can't be combined with `reservation_ids`.                                                                                             |        -        |    string    |  false   |
+| `worker_pool.setup_raid`              | Attempt to create a RAID 0 from extra disks to be used for persistent container storage. Can't be used with `setup_raid_hdd` nor `setup_raid_sdd`.                                                                                                                                |      false      |     bool     |  false   |
+| `worker_pool.setup_raid_hdd`          | Attempt to create a RAID 0 from extra Hard Disk drives only, to be used for persistent container storage. Can't be used with `setup_raid` nor `setup_raid_sdd`.                                                                                                                   |      false      |     bool     |  false   |
+| `worker_pool.setup_raid_ssd`          | Attempt to create a RAID 0 from extra Solid State Drives only, to be used for persistent container storage.  Can't be used with `setup_raid` nor `setup_raid_hdd`.                                                                                                                |      false      |     bool     |  false   |
+| `worker_pool.setup_raid_ssd_fs`       | When set to `true` file system will be created on SSD RAID device and will be mounted on `/mnt/node-local-ssd-storage`. To use the raw device set it to `false`.                                                                                                                  |      false      |     bool     |  false   |
+
 
 ## Applying
 
diff --git a/pkg/components/velero/restic/restic.go b/pkg/components/velero/restic/restic.go
index dba71540..298267bd 100644
--- a/pkg/components/velero/restic/restic.go
+++ b/pkg/components/velero/restic/restic.go
@@ -29,8 +29,9 @@ const indentation = 6
 
 // Configuration contains Restic specific parameters.
 type Configuration struct {
-	Credentials           string                 `hcl:"credentials"`
-	BackupStorageLocation *BackupStorageLocation `hcl:"backup_storage_location,block"`
+	Credentials             string                 `hcl:"credentials"`
+	RequireVolumeAnnotation bool                   `hcl:"require_volume_annotation,optional"`
+	BackupStorageLocation   *BackupStorageLocation `hcl:"backup_storage_location,block"`
 }
 
 // BackupStorageLocation configures the backup storage location.
diff --git a/pkg/components/velero/restic/template.go b/pkg/components/velero/restic/template.go
index 2f566303..f69b22f1 100644
--- a/pkg/components/velero/restic/template.go
+++ b/pkg/components/velero/restic/template.go
@@ -27,6 +27,9 @@ configuration:
     bucket: {{ .Configuration.BackupStorageLocation.Bucket }}
     config:
       region: {{ .Configuration.BackupStorageLocation.Region }}
+  {{- if not .Configuration.RequireVolumeAnnotation }}
+  defaultVolumesToRestic: true
+  {{- end }}
 deployRestic: true
 snapshotsEnabled: false
 restic:
diff --git a/pkg/platform/packet/packet.go b/pkg/platform/packet/packet.go
index 9a93d743..804370b3 100644
--- a/pkg/platform/packet/packet.go
+++ b/pkg/platform/packet/packet.go
@@ -19,7 +19,6 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
-	"reflect"
 	"sort"
 	"strconv"
 	"strings"
@@ -492,11 +491,11 @@ func (c *config) checkWorkerPoolNamesUnique() hcl.Diagnostics {
 func (c *config) checkReservationIDs() hcl.Diagnostics {
 	var diagnostics hcl.Diagnostics
 
-	d := checkEachReservation(c.ReservationIDs, c.ReservationIDsDefault, c.ClusterName, controller, c.ControllerCount)
+	d := checkEachReservation(c.ReservationIDs, c.ReservationIDsDefault, c.ClusterName, controller)
 	diagnostics = append(diagnostics, d...)
 
 	for _, w := range c.WorkerPools {
-		d := checkEachReservation(w.ReservationIDs, w.ReservationIDsDefault, w.Name, worker, w.Count)
+		d := checkEachReservation(w.ReservationIDs, w.ReservationIDsDefault, w.Name, worker)
 		diagnostics = append(diagnostics, d...)
 	}
 
@@ -534,9 +533,7 @@ func (c *config) validateOSVersion() hcl.Diagnostics {
 // pool are not mixed between using "next-available" and specific UUIDs, as this
 // can't work reliably.
 // For more info, see comment when calling terraformCreateReservations().
-//
-//nolint:funlen,lll
-func checkEachReservation(reservationIDs map[string]string, resDefault, name string, role nodeRole, count int) hcl.Diagnostics {
+func checkEachReservation(reservationIDs map[string]string, resDefault, name string, role nodeRole) hcl.Diagnostics {
 	var diagnostics hcl.Diagnostics
 
 	errorPrefix := "Worker pool"
@@ -570,21 +567,15 @@ func checkEachReservation(reservationIDs map[string]string, resDefault, name str
 
 	// Check reservation_ids map doesn't use "next-available" as a value.
 	for _, v := range reservationIDs {
-		if v == "next-available" {
-			diagnostics = append(diagnostics, &hcl.Diagnostic{
-				Severity: hcl.DiagError,
-				Summary:  fmt.Sprintf("%v reservations_ids entries can't use \"next-available\"", errorPrefix),
-				Detail:   fmt.Sprintf("%v: %q uses it, use specific UUIDs or reservations_ids_default only", errorPrefix, name),
-			})
+		if v != "next-available" {
+			continue
 		}
 
-		if v == "" {
-			diagnostics = append(diagnostics, &hcl.Diagnostic{
-				Severity: hcl.DiagError,
-				Summary:  fmt.Sprintf("%v reservations_ids entries can't be empty", errorPrefix),
-				Detail:   fmt.Sprintf("%v: %q is empty", errorPrefix, name),
-			})
-		}
+		diagnostics = append(diagnostics, &hcl.Diagnostic{
+			Severity: hcl.DiagError,
+			Summary:  fmt.Sprintf("%v reservations_ids entries can't use \"next-available\"", errorPrefix),
+			Detail:   fmt.Sprintf("%v: %q uses it, use specific UUIDs or reservations_ids_default only", errorPrefix, name),
+		})
 	}
 
 	// Check format is:
@@ -598,14 +589,6 @@ func checkEachReservation(reservationIDs map[string]string, resDefault, name str
 	d := checkResFormat(reservationIDs, name, errorPrefix, resPrefix)
 	diagnostics = append(diagnostics, d...)
 
-	if len(reservationIDs) > 0 && len(reservationIDs) != count {
-		diagnostics = append(diagnostics, &hcl.Diagnostic{
-			Severity: hcl.DiagError,
-			Summary:  fmt.Sprintf("%v reservations_ids does not match count field", errorPrefix),
-			Detail:   fmt.Sprintf("%v: %q all nodes in pool must have reservation IDs set", errorPrefix, name),
-		})
-	}
-
 	return diagnostics
 }
 
@@ -614,14 +597,7 @@ func checkEachReservation(reservationIDs map[string]string, resDefault, name str
 func checkResFormat(reservationIDs map[string]string, name, errorPrefix, resPrefix string) hcl.Diagnostics {
 	var diagnostics hcl.Diagnostics
 
-	deviceIndexes := []int{}
-	expectedIndexes := []int{}
-	index := 0
-
 	for key := range reservationIDs {
-		expectedIndexes = append(expectedIndexes, index)
-		index++
-
 		hclErr := &hcl.Diagnostic{
 			Severity: hcl.DiagError,
 			Summary:  "Invalid reservation ID",
@@ -648,24 +624,11 @@ func checkResFormat(reservationIDs map[string]string, name, errorPrefix, resPref
 		// Check a valid number is used after "controller-" or
 		// "worker-".
 		index := resEntry[1]
-
-		i, err := strconv.Atoi(index)
-		if err == nil {
-			deviceIndexes = append(deviceIndexes, i)
+		if _, err := strconv.Atoi(index); err != nil {
+			diagnostics = append(diagnostics, hclErr)
+			// Don't duplicate the same error, show it one per key.
 			continue
 		}
-
-		diagnostics = append(diagnostics, hclErr)
-	}
-
-	sort.Ints(deviceIndexes)
-
-	if !reflect.DeepEqual(deviceIndexes, expectedIndexes) {
-		diagnostics = append(diagnostics, &hcl.Diagnostic{
-			Severity: hcl.DiagError,
-			Summary:  "Invalid reservation ID",
-			Detail:   fmt.Sprintf("%v: reservation IDs must be sequential and start from 0", errorPrefix),
-		})
 	}
 
 	return diagnostics


Test patch:
diff --git a/pkg/platform/packet/packet_test.go b/pkg/platform/packet/packet_test.go
index 3d15d99b..92629eae 100644
--- a/pkg/platform/packet/packet_test.go
+++ b/pkg/platform/packet/packet_test.go
@@ -15,7 +15,7 @@
 package packet
 
 import (
-	"reflect"
+	"sort"
 	"testing"
 )
 
@@ -150,101 +150,118 @@ func TestValidateOSVersion(t *testing.T) {
 	}
 }
 
-//nolint:funlen
-func TestCheckValidConfig(t *testing.T) {
-	cases := map[string]struct {
-		mutateF     func(*config)
-		expectError bool
+func TestCheckResFormatPrefixValidInput(t *testing.T) {
+	r := map[string]string{"worker-2": "", "worker-3": ""}
+
+	if d := checkResFormat(r, "", "", "worker"); d.HasErrors() {
+		t.Errorf("Validation failed and shouldn't for: %v", r)
+	}
+}
+
+func TestCheckResFormatPrefixInvalidInput(t *testing.T) {
+	r := map[string]string{"broken-1": "", "worker-1-2": "", "worker-a": ""}
+
+	if d := checkResFormat(r, "", "", "worker"); !d.HasErrors() {
+		t.Errorf("Should fail with res: %v", r)
+	}
+}
+
+func TestCheckEachReservationValidInput(t *testing.T) {
+	cases := []struct {
+		role           nodeRole
+		resDefault     string
+		reservationIDs map[string]string
 	}{
-		"base_config_is_valid": {
-			mutateF: func(*config) {},
-		},
-		"reservation_IDs_for_controller_nodes_can't_have_random_prefix": {
-			mutateF: func(c *config) {
-				c.ReservationIDs = map[string]string{"foo-1": "bar"}
-			},
-			expectError: true,
-		},
-		"reservation_IDs_for_controller_nodes_must_be_prefixed_with_'controller'": {
-			mutateF: func(c *config) {
-				c.ControllerCount = 1
-				c.ReservationIDs = map[string]string{"controller-0": "bar"}
-			},
-		},
-		"reservation_IDs_for_worker_nodes_can't_have_random_prefix": {
-			mutateF: func(c *config) {
-				c.WorkerPools[0].ReservationIDs = map[string]string{"foo-0": "bar"}
+		{
+			// Test validates worker config.
+			role: worker,
+			reservationIDs: map[string]string{
+				"worker-2": "",
+				"worker-3": "",
 			},
-			expectError: true,
 		},
-		"reservation_IDs_for_worker_nodes_must_be_prefixed_with_'worker'": {
-			mutateF: func(c *config) {
-				c.WorkerPools[0].Count = 1
-				c.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "bar"}
+		{
+			// Test validates controller config.
+			role: controller,
+			reservationIDs: map[string]string{
+				"controller-2": "",
+				"controller-3": "",
 			},
 		},
-		"reservation_IDs_for_worker_nodes_can't_be_mixed_default_reservation_ID": {
-			mutateF: func(c *config) {
-				c.WorkerPools[0].ReservationIDsDefault = "next-available"
-				c.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "bar"}
-			},
-			expectError: true,
+		{
+			// Test works if resDefault is set and no
+			// reservationIDs.
+			role:       controller,
+			resDefault: "next-available",
 		},
-		"reservation_IDs_for_worker_nodes_can't_be_set_to_'next-available'": {
-			mutateF: func(c *config) {
-				c.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "next-available"}
+	}
+
+	for _, tc := range cases {
+		if d := checkEachReservation(tc.reservationIDs, tc.resDefault, "", tc.role); d.HasErrors() {
+			t.Errorf("Should not fail with valid input: %v", tc)
+		}
+	}
+}
+
+func TestCheckEachReservationInvalidInput(t *testing.T) {
+	cases := []struct {
+		role           nodeRole
+		resDefault     string
+		reservationIDs map[string]string
+	}{
+		{
+			// Test if nodeRole is worker, reservation should be
+			// "worker-" not "controller".
+			role: worker,
+			reservationIDs: map[string]string{
+				"controller-1": "",
 			},
-			expectError: true,
 		},
-		"reservation_IDs_can't_be_empty": {
-			mutateF: func(c *config) {
-				c.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": ""}
+		{
+			// Idem previous but vice-versa.
+			role: controller,
+			reservationIDs: map[string]string{
+				"worker-3": "",
 			},
-			expectError: true,
 		},
-		"reservation_IDs_must_be_sequential": {
-			mutateF: func(c *config) {
-				c.WorkerPools[0].Count = 2
-				c.WorkerPools[0].ReservationIDs = map[string]string{
-					"worker-0": "foo",
-					"worker-1": "bar",
-				}
+		{
+			// Test if resDefault is set to next-available,
+			// reservationIDs should be empty.
+			role:       worker,
+			resDefault: "next-available",
+			reservationIDs: map[string]string{
+				"worker-3": "",
 			},
 		},
-		"not_sequential_reservation_IDs_are_invalid": {
-			mutateF: func(c *config) {
-				c.WorkerPools[0].ReservationIDs = map[string]string{
-					"worker-0": "foo",
-					"worker-2": "bar",
-				}
+		{
+			// Test reservationIDs should never be set to
+			// "next-available".
+			role: worker,
+			reservationIDs: map[string]string{
+				"worker-3": "next-available",
 			},
-			expectError: true,
 		},
 	}
 
-	for name, c := range cases {
-		c := c
-
-		t.Run(name, func(t *testing.T) {
-			config := baseConfig()
-
-			c.mutateF(config)
-
-			diagnostics := config.checkValidConfig()
-
-			if diagnostics.HasErrors() && !c.expectError {
-				t.Fatalf("unexpected validation error: %v", diagnostics)
-			}
-
-			if !diagnostics.HasErrors() && c.expectError {
-				t.Fatalf("expected error, but validation passed")
-			}
-		})
+	for _, tc := range cases {
+		if d := checkEachReservation(tc.reservationIDs, tc.resDefault, "", tc.role); !d.HasErrors() {
+			t.Errorf("No error detected in invalid input: %v", tc)
+		}
 	}
 }
 
-func baseConfig() *config {
-	return &config{
+//nolint: funlen
+func TestTerraformAddDeps(t *testing.T) {
+	type testCase struct {
+		// Config to test
+		cfg config
+		// Expected config after running the test
+		exp config
+	}
+
+	var cases []testCase
+
+	base := config{
 		ClusterName: "c",
 		WorkerPools: []workerPool{
 			{
@@ -255,91 +272,86 @@ func baseConfig() *config {
 			},
 		},
 	}
-}
 
-//nolint: funlen
-func TestTerraformAddDeps(t *testing.T) {
-	cases := map[string]struct {
-		configF         func(*config)
-		expectedConfigF func(*config)
-	}{
-		"worker pool without reservation IDs depends on worker pool with reservation ID": {
-			func(c *config) {
-				c.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "dummy"}
-			},
-			func(c *config) {
-				c.WorkerPools[1].NodesDependOn = []string{poolTarget("1", "worker_nodes_ids")}
-			},
-		},
-		"all worker pools without reservation IDs depends on worker pool with reservation ID": {
-			func(c *config) {
-				c.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "dummy"}
-				c.WorkerPools = append(c.WorkerPools, workerPool{Name: "3"})
-			},
-			func(c *config) {
-				c.WorkerPools[1].NodesDependOn = []string{poolTarget("1", "worker_nodes_ids")}
-			},
-		},
-		"worker pool without reservation IDs depends on all worker pools with reservation IDs": {
-			func(c *config) {
-				c.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "dummy"}
-				c.WorkerPools[1].ReservationIDs = map[string]string{"worker-0": "dummy"}
-				c.WorkerPools = append(c.WorkerPools, workerPool{Name: "3"})
-			},
-			func(c *config) {
-				c.WorkerPools[2].NodesDependOn = []string{
-					poolTarget("1", "worker_nodes_ids"),
-					poolTarget("2", "worker_nodes_ids"),
-				}
-			},
-		},
-		"worker pools without reservation IDs depends on controller nodes with reservation IDs": {
-			func(c *config) {
-				c.ReservationIDs = map[string]string{"controller-0": "dummy"}
-			},
-			func(c *config) {
-				c.WorkerPools[0].NodesDependOn = []string{clusterTarget("1", "device_ids")}
-				c.WorkerPools[1].NodesDependOn = []string{clusterTarget("1", "device_ids")}
-			},
-		},
-		"worker pool without reservation IDs depends on controller nodes and worker pools with reservation IDs": {
-			func(c *config) {
-				c.ReservationIDs = map[string]string{"controller-0": "dummy"}
-				c.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "dummy"}
-			},
-			func(c *config) {
-				c.WorkerPools[1].NodesDependOn = []string{clusterTarget("1", "device_ids"), poolTarget("1", "device_ids")}
-			},
-		},
+	// Test WorkerPool w/o res depends on 1 WorkerPool with res
+	test := base
+	test.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "dummy"}
+	exp := test
+	exp.WorkerPools[1].NodesDependOn = []string{poolTarget("1", "worker_nodes_ids")}
+
+	cases = append(cases, testCase{test, exp})
+
+	// Test 2 WorkerPools w/o res depend on 2 WorkerPool with rest
+	test = base
+	test.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "dummy"}
+	test.WorkerPools = append(test.WorkerPools, workerPool{Name: "3"})
+	exp = test
+	exp.WorkerPools[1].NodesDependOn = []string{poolTarget("1", "worker_nodes_ids")}
+
+	cases = append(cases, testCase{test, exp})
+
+	// Test 1 WorkerPools w/o res depend on 2 WorkerPool with res
+	test = base
+	test.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "dummy"}
+	test.WorkerPools[1].ReservationIDs = map[string]string{"worker-0": "dummy"}
+	test.WorkerPools = append(test.WorkerPools, workerPool{Name: "3"})
+	exp = test
+	exp.WorkerPools[2].NodesDependOn = []string{
+		poolTarget("1", "worker_nodes_ids"),
+		poolTarget("2", "worker_nodes_ids"),
 	}
 
-	for name, c := range cases {
-		c := c
+	cases = append(cases, testCase{test, exp})
 
-		t.Run(name, func(t *testing.T) {
-			// Create copy of base config.
-			config := baseConfig()
+	// Test 2 WorkerPools w/o res depend on controllers
+	test = base
+	test.ReservationIDs = map[string]string{"controller-0": "dummy"}
+	exp = test
+	exp.WorkerPools[0].NodesDependOn = []string{clusterTarget("1", "device_ids")}
+	exp.WorkerPools[1].NodesDependOn = []string{clusterTarget("1", "device_ids")}
 
-			// Mutate it.
-			c.configF(config)
+	cases = append(cases, testCase{test, exp})
 
-			// Copy mutated config.
-			expectedConfig := config
+	// Test 1 WorkerPools w/o res depends on controllers and WorkerPool with
+	// res
+	test = base
+	test.ReservationIDs = map[string]string{"controller-0": "dummy"}
+	test.WorkerPools[0].ReservationIDs = map[string]string{"worker-0": "dummy"}
+	exp = test
+	exp.WorkerPools[1].NodesDependOn = []string{clusterTarget("1", "device_ids"), poolTarget("1", "device_ids")}
 
-			// Mutate to expected config.
-			c.expectedConfigF(expectedConfig)
+	cases = append(cases, testCase{test, exp})
+
+	for tcIdx, tc := range cases {
+		test := tc.cfg
+		exp := tc.exp
 
-			// Add dependencies.
-			config.terraformAddDeps()
+		test.terraformAddDeps()
 
-			for i, workerPool := range config.WorkerPools {
-				dependencies := workerPool.NodesDependOn
-				expectedDependencies := expectedConfig.WorkerPools[i].NodesDependOn
+		for i, w := range test.WorkerPools {
+			ret := w.NodesDependOn
+			expRet := exp.WorkerPools[i].NodesDependOn
 
-				if !reflect.DeepEqual(dependencies, expectedDependencies) {
-					t.Fatalf("Expected %v, got %v", expectedDependencies, dependencies)
-				}
+			if equal := cmpSliceString(ret, expRet); !equal {
+				t.Errorf("In test %v, expected %v, got %v", tcIdx, expRet, ret)
 			}
-		})
+		}
 	}
 }
+
+func cmpSliceString(a, b []string) bool {
+	if len(a) != len(b) {
+		return false
+	}
+
+	sort.Strings(a)
+	sort.Strings(b)
+
+	for index, elem := range a {
+		if elem != b[index] {
+			return false
+		}
+	}
+
+	return true
+}