+
+
+
+If you are using the legacy Terraform modules
+([AWS](https://github.com/MaterializeInc/terraform-aws-materialize),
+[GCP](https://github.com/MaterializeInc/terraform-gcp-materialize), or
+[Azure](https://github.com/MaterializeInc/terraform-azure-materialize)),
+we recommend migrating to the [new supported Terraform
+modules](https://github.com/MaterializeInc/materialize-terraform-self-managed)
+before opting in to the `v1` CRD.
+
+The new modules include built-in support for the conversion webhooks used by
+the `v1` CRD, including cert-manager installation and network policy
+configuration. The legacy modules do not include these changes, so you would
+need to apply them manually (see the **Manual** tab).
+
+For migration guidance, see the documentation for your cloud provider:
+
+- [AWS migration guide](https://github.com/MaterializeInc/materialize-terraform-self-managed/tree/main/aws/examples/migration)
+- [GCP migration guide](https://github.com/MaterializeInc/materialize-terraform-self-managed/tree/main/gcp/examples/migration)
+- [Azure migration guide](https://github.com/MaterializeInc/materialize-terraform-self-managed/tree/main/azure/examples/migration)
+
+
+
+
+If you are not using our Terraform modules, you **must** complete the following
+steps before enabling the `v1` CRD:
+
+**1. Install cert-manager**
+
+The conversion webhook requires a TLS certificate.
+The Helm chart defaults to using [cert-manager](https://cert-manager.io/)
+to automatically create and manage this certificate. cert-manager must be
+installed **before** enabling the `v1` CRD.
+
+If you prefer to provide your own certificate instead of using cert-manager,
+set the following Helm values:
+- `operator.certificate.source`: `secret`
+- `operator.certificate.secretName`: the name of the Kubernetes Secret
+ containing `ca.crt`, `tls.crt`, and `tls.key` entries.
+
+**2. Allow network access to the webhook port**
+
+The conversion webhooks require the Kubernetes API server to reach the
+`orchestratord` pod on port `8001`. If your cluster enforces network policies
+or cloud-level firewall rules, you must allow ingress traffic on TCP port
+`8001` from the API server to pods with the label
+`app.kubernetes.io/name: materialize-operator`.
+
+**Kubernetes NetworkPolicy:** Add a policy that allows ingress from the
+Kubernetes API server on port `8001` to the `materialize-operator` pods in the
+namespace where the operator is deployed:
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: allow-api-server-ingress-to-conversion-webhook
+ namespace: materialize # the namespace where the operator runs
+spec:
+ podSelector:
+ matchLabels:
+ app.kubernetes.io/name: materialize-operator
+ policyTypes:
+ - Ingress
+ ingress:
+ - ports:
+ - protocol: TCP
+ port: 8001
+```
+
+**Cloud firewall rules (e.g., AWS security groups, GCP firewall rules):**
+Ensure the node security group or firewall allows inbound TCP traffic on
+port `8001` from the Kubernetes control plane. For example, on AWS, add an
+ingress rule to the EKS node security group allowing port `8001` from the
+cluster security group. On GCP with private clusters, add a firewall rule
+allowing port `8001` from the GKE control plane CIDR.
+
+For a complete example of the required changes across AWS, Azure, and GCP,
+see [this pull request](https://github.com/MaterializeInc/materialize-terraform-self-managed/pull/160).
+
+**3. Enable the v1 CRD**
+
+Once the prerequisites above are in place, set the following Helm value when
+installing or upgrading the operator:
+
+```yaml
+operator:
+ args:
+ installV1CRD: true
+```
+
+This installs the `v1` version of the Materialize CRD and the conversion
+webhook that converts between `v1` and `v1alpha1`.
+
+
+