// Module included in the following assembly for OSD:
//
// * applications/deployments/osd-config-custom-domains-applications.adoc

:_mod-docs-content-type: PROCEDURE
[id="osd-applications-config-custom-domains_{context}"]
= Configure custom domains for applications

[role="_abstract"]
The top-level domains (TLDs) are owned by the customer that is operating the {product-title} cluster. The Custom Domains Operator sets up a new ingress controller with a custom certificate as a second day operation. The public DNS record for this ingress controller can then be used by an external DNS to create a wildcard CNAME record for use with a custom domain.

[NOTE]
====
Custom API domains are not supported because Red Hat controls the API domain. However, customers can change their application domains. For private custom domains with a private `IngressController`, set `.spec.scope` to `Internal` in the `CustomDomain` CR.
====

.Prerequisites

* A user account with `dedicated-admin` privileges
* A unique domain or wildcard domain, such as `*.apps.<company_name>.io`
* A custom certificate or wildcard custom certificate, such as `CN=*.apps.<company_name>.io`
* Access to a cluster with the latest version of the `oc` CLI installed

[IMPORTANT]
Do not use the reserved names `default` or `apps*`, such as `apps` or `apps2`, in the `metadata/name:` section of the `CustomDomain` CR.

.Procedure

. Create a new TLS secret from a private key and a public certificate, where `fullchain.pem` and `privkey.pem` are your public or private wildcard certificates.
+
.Example
[source,terminal]
----
$ oc create secret tls <name>-tls --cert=fullchain.pem --key=privkey.pem -n <my_project>
----

. Create a new `CustomDomain` custom resource (CR):
+
.Example `<company_name>-custom-domain.yaml`
[source,yaml]
----
apiVersion: managed.openshift.io/v1alpha1
kind: CustomDomain
metadata:
  name: <company_name>
spec:
  domain: apps.<company_name>.io
  scope: External
  loadBalancerType: Classic
  certificate:
    name: <name>-tls
    namespace: <my_project>
  routeSelector:
    matchLabels:
     route: acme
  namespaceSelector:
    matchLabels:
     type: sharded
----
+
--
where:

`spec.domain`:: Specifies the custom domain.
`spec.loadBalancerType`:: Specifies the type of load balancer for your custom domain. This type can be the default `classic` or `NLB` if you use a network load balancer.
`spec.certificate.name`:: Specifies the secret created in the earlier step.
`spec.routeSelector`:: Optional. Filters the set of routes serviced by the `CustomDomain` ingress. If no value is provided, the default is no filtering.
`spec.namespaceSelector`:: Optional. Filters the set of namespaces serviced by the `CustomDomain` ingress. If no value is provided, the default is no filtering.
--

. Apply the CR:
+
.Example
[source,terminal]
----
$ oc apply -f <company_name>-custom-domain.yaml
----

. Get the status of your newly created CR:
+
[source,terminal]
----
$ oc get customdomains
----
+
.Example output
[source,terminal]
----
NAME               ENDPOINT                                                    DOMAIN                       STATUS
<company_name>     xxrywp.<company_name>.cluster-01.opln.s1.openshiftapps.com  *.apps.<company_name>.io     Ready
----

ifdef::openshift-rosa[]
. Using the endpoint value, add a new wildcard CNAME recordset to your managed DNS provider, such as Route53.
endif::openshift-rosa[]
ifndef::openshift-rosa[]
. Using the endpoint value, add a new wildcard CNAME recordset to your managed DNS provider, such as Route53, Azure DNS, or Google DNS.
endif::openshift-rosa[]

+
.Example
[source,terminal]
----
*.apps.<company_name>.io -> xxrywp.<company_name>.cluster-01.opln.s1.openshiftapps.com
----

. Create a new application and expose it:
+
.Example
[source,terminal]
----
$ oc new-app --docker-image=docker.io/openshift/hello-openshift -n my-project
----
+
[source,terminal]
----
$ oc create route <route_name> --service=hello-openshift hello-openshift-tls --hostname hello-openshift-tls-my-project.apps.<company_name>.io -n my-project
----
+
[source,terminal]
----
$ oc get route -n my-project
----
+
[source,terminal]
----
$ curl https://hello-openshift-tls-my-project.apps.<company_name>.io
Hello OpenShift!
----

.Troubleshooting
* link:https://access.redhat.com/solutions/5419501[Error creating TLS secret]
* link:https://access.redhat.com/solutions/6546011[Troubleshooting: `CustomDomain` in `NotReady` state]