Configure an IBM Cloud Code Engine application to use custom domains

23 May 2023

5 min read

IBM Cloud Code Engine is a fully managed, serverless platform that runs your containerized workloads, including web apps, microservices, event-driven functions or batch jobs. Code Engine even builds container images for you from your source code.

All these workloads can seamlessly work together because they are all hosted within the same Kubernetes infrastructure. The Code Engine experience is designed so that you could focus on writing code and not worry about the infrastructure that is needed to host it.

Prerequisites

    • Appropriate permissions to use the IBM Cloud Code Engine service. See here for how to manage these.
    • An application running on IBM Cloud Code Engine. You can deploy the test application from here.
    • Access to modify DNS of a public domain/hostname. If you own a domain or purchased one, you will most likely have access to manage DNS for that domain. In the example, we have used IBM Cloud Internet Services that support CNAME flattening feature to enable us to use root domain.
    • TLS/SSL certificate signed by a public certificate authority.

    In this example, the test application is deployed on IBM Cloud Code Engine. The original hostname looks something similar to this https://application-27.zx67dfvbl7l.us-south.codeengine.appdomain.cloud/. We’ll expose this application using two custom domains:

    • https://example.org
    • https://codeengine.example.org

    Step-by-step instructions

    Refer this document and the below steps to create the TLS certificates for both domains and use them to expose this test application. You can use Let’s Encrypt CA as an example to request TLS certificates for these custom domains. However, you can also use a TLS certificate from any of the public certificate authorities.

    We’ll follow these steps to accomplish our goals:

    1. Generate CSR for TLS certificate and get it signed from CA.
    2. Add your domain to Code Engine application UI.
    3. Create CNAME record in DNS for your domain name.

    1. Generate CSR for TLS certificate and get it signed from CA

    To generate a valid signed TLS certificate from Let’s Encrypt CA, you can use the Certbot client to generate the CSR and get it signed from CA. First, you need to install the Certbot using these instructions.

    Use the following command to start the process for the certificate generation:

    certbot certonly --manual --preferred-challenges dns --email contact@example.org --server https://acme-v02.api.letsencrypt.org/directory --agree-tos --domain codeengine.example.org
    
    certbot certonly --manual --preferred-challenges dns --email contact@example.org --server https://acme-v02.api.letsencrypt.org/directory --agree-tos --domain example.org
    

    Then, it should ask you for the domain ownership verification step:

    root@jumpbox:~# certbot certonly --manual --preferred-challenges dns --email contact@example.org --server https://acme-v02.api.letsencrypt.org/directory --agree-tos --domain codeengine.example.org
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Requesting a certificate for codeengine.example.org
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Please deploy a DNS TXT record under the name:
    
    _acme-challenge.codeengine.example.org
    
    with the following value:
    
    Fq2wbN9mUSfnWZkGXyaEgVaOm-_9RB4cv4zJEp44Sbg
    
    Before continuing, verify the TXT record has been deployed. Depending on the DNS
    provider, this may take some time, from a few seconds to multiple minutes. You can
    check if it has finished deploying with aid of online tools, such as the Google
    Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.codeengine.example.org.
    Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
    value(s) you've just added.
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Press Enter to Continue
    

    Let’s add the verification TXT records for both domains in the DNS as per the below:

    codeengine.example.org TXT Fq2wbN9mUSfnWZkGXyaEgVaOm-_9RB4cv4zJEp44Sbg
    
    example.org TXT DfjSDFFDbN9vccdSDnjnkSNSNKx-_9vccdSDnZvccdSDn
    

    Now, you need to create a TXT record with the above value in your domain’s DNS servers. The DNS servers for your domain might have been provided by your domain registrar or these can be hosted somewhere else. After you add this DNS record, you can verify it using dig ornslookup :

    % dig txt _acme-challenge.codeengine.example.org. +short
    "Fq2wbN9mUSfnWZkGXyaEgVaOm-_9RB4cv4zJEp44Sbg"
    

    After you press Enter or Return, you should see something like the following:

    Successfully received certificate.
    Certificate is saved at: /etc/letsencrypt/live/codeengine.example.org/fullchain.pem
    Key is saved at: /etc/letsencrypt/live/codeengine.example.org/privkey.pem
    This certificate expires on 2023-07-20.
    These files will be updated when the certificate renews.
    
    NEXT STEPS:
    - This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    If you like Certbot, please consider supporting our work by:
    * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
    * Donating to EFF: https://eff.org/donate-le
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    

    You got two files:

    <code>/etc/letsencrypt/live/codeengine.example.org/fullchain.pem
    
    • This is your TLS certificate with full root-ca chain certificates. The contents should be something like this:
    -----BEGIN CERTIFICATE-----
    MIIFNDCCBBygAwIBAgISBOLyU
    ------
    ------
    ------
    cRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
    Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
    -----END CERTIFICATE-----
    
    /etc/letsencrypt/live/codeengine.example.org/privkey.pem
    
    • This is the private key for your TLS certificate. The content of the private key file should be something like the following:
    -----BEGIN PRIVATE KEY-----
    MIIEvwIBADANBgkqhkiG9w0BAQEF
    ------
    ------
    ------
    BAZQ4dZS/TXFRMQcgNL3nWGk42YSOYAjqJNceX6rQMSoxDiCdb6e+
    +pT6jcKsENz88M3dpNQNi1OSUQ==
    -----END PRIVATE KEY-----
    

    2. Add your domain to Code Engine application UI

    Since you have TLS certificate and key available, you can now proceed to add the custom domain to the IBM Cloud Code Engine application from the IBM Cloud console.

    • Go here and follow Projects > Your project name > Applications > Application name > Domain mappings tab
    • Select the application for which you want to use a custom domain.
    • Select Domain mappings from the top bar menu.
    • Here, you need to click on the blue button named Create under the section titled Custom domain mappings.
    • A new setup wizard should open like the screenshot above. You need to paste the contents from the file fullchain.pem in the text box titled Certificate chain and file privkey.pem to the text box titled Private key.
    • Under the section titled Domain name and target application, type the actual custom domain hostname:
      • Domain name: Type “example.org” in this editable text field.
      • CNAME Target: Pref-filled text should be there, which we need to create a CNAME record for this domain name.
    example.org CNAME custom.zx67dfvbl7l.us-south.codeengine.appdomain.cloud
    
    codeengine.example.org CNAME custom. zx67dfvbl7l.us-south.codeengine.appdomain.cloud
    

    3. Create a CNAME record in DNS for your domain name

    This is an important step. Let’s create a CNAME record in your domain’s DNS servers pointing to the value from the CNAME target box.

    After you have created the CNAME record, proceed by selecting the Create button to finish creating the custom domain name mapping. This should take few minutes to be fully activated in the system.

    If you want to use your root domain (example.org) instead of a subdomain like codeengine.example.org, you may want to use the CNAME flattening feature of IBM Cloud Internet Services. For more details refer to the links below.

    If everything goes fine, you should be able to access your application using your custom domain:

    % curl -k https://example.org Hello World from: . ___ __ ____ ____ ./ __)/ \( \( __) ( (__( O )) D ( ) _) .\___)\__/(____/(____) .____ __ _ ___ __ __ _ ____ ( __)( ( \ / __)( )( ( \( __) .) _) / /( (_ \ )( / / ) _) (____)\_)__) \___/(__)\_)__)(____) Some Env Vars: -------------- CE_APP=application-27 CE_DOMAIN=us-south.codeengine.appdomain.cloud CE_SUBDOMAIN=z87ya4p4l7l HOME=/root HOSTNAME=application-27-00004-deployment-6fff67f786-f82qm K_REVISION=application-27-00004 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=8080 PWD=/ SHLVL=1 z=Set env var 'SHOW' to see all variables
    

    Congratulations, we have successfully exposed our IBM Cloud Code Engine application via custom domains.

    Learn more

    For more information on related IBM Cloud services please refer to the links below.

    Get started with IBM Cloud Code Engine https://www.ibm.com/cloud/code-engine

    Author

    Abhishek Kumar

    Manager - IBM Cloud PaaS Support