This guide walks you through packaging an AWS EKS Traefik whomami application and deploying it to an Install.

This App Config can be found in a GitHub repository.

Prerequisites

What You Will Create

This tutorial will walk you through creating the following:

You can alternatively clone the example-app-configs repository which includes the eks-simple App Config versus creating each config file manually. This guide is meant to explain the concepts behind each config file, so you can create your own App Configs in the future.

Configure App

To configure the app, you will create several TOML config files. In each section below we will provide you with configuration snippets for the app itself as well as it’s components.

Create App

Define the app itself and give it a name. This will create the app in app.nuon.co

mkdir eks-simple
cd eks-simple
nuon apps create --name=eks-simple --no-template

You should see the new App in the dashboard.

Inputs

Inputs are customer-specific configs that are entered when you install the App in the customer’s cloud account. They will be displayed in the Dashboard UI. Inputs are optional.

In the App root directory, create a file named inputs.toml and add the following:

inputs.toml
#:schema https://api.nuon.co/v1/general/config-schema?source=inputs
[[group]]
name         = "dns"
description  = "DNS Configrations"
display_name = "Configurations for the root domain for Route53"

[[input]]
name         = "sub_domain"
description  = "The sub domain for the Whoami service"
default      = "whoami"
display_name = "Sub Domain"
group        = "dns"

This Input defines a subdomain for the Whoami service that will be deployed in the customer’s AWS account. The customer will be prompted to enter this value when they create an Install of the App. It will default to whoami, but the customer can change it to whatever they want.

Sandbox

Nuon provides a set of Nuon Managed Sandboxes that can be used to provision the infrastructure needed for your app. The aws-eks-sandbox will provide everything you need to run an EKS, from the EKS cluster down to the VPC.

Your App references these Sandboxes in the sandbox.toml file.

In the App root directory, create a file named sandbox.toml and add the following:

sandbox.toml
terraform_version = "1.11.3"

[public_repo]
directory = "."
repo      = "nuonco/aws-eks-sandbox"
branch    = "main"

[vars]
cluster_name         = "n-{{.nuon.install.id}}"
enable_nuon_dns      = "true"
public_root_domain   = "{{ .nuon.install.id }}.nuon.run"
internal_root_domain = "internal.{{ .nuon.install.id }}.nuon.run"

[[var_file]]
contents = "./sandbox.tfvars"

With enable_nuon_dns set to true, the Sandbox will create a Route53 DNS zone for the install, allowing you to access the services deployed in the customer’s AWS account using a Nuon-managed domain. The config uses the Install ID as the subdomain, which will be unique for each install.

The Sandbox expects variables, some of which are defined in the vars section while others are defined in the sandbox.tfvars file.

In the App root directory, create a file named sandbox.tfvars and add the following:

sandbox.tfvars
maintenance_role_eks_access_entry_policy_associations = {
  eks_admin = {
    policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy"
    access_scope = {
      type = "cluster"
    }
  }
  eks_view = {
    policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
    access_scope = {
      type = "cluster"
    }
  }
}

additional_namespaces = ["whoami"]

maintenance_cluster_role_rules_override = [{
  "apiGroups" = ["*"]
  "resources" = ["*"]
  "verbs"     = ["*"]
}]

min_size = 2
max_size = 3
desired_capacity = 2

Notice you can manage compute costs by setting the min_size, max_size, and desired_capacity of the EKS cluster.

Components

Components are the building blocks of your App and where a software vendor’s application is installed on top of the Sandbox infrastructure.

In this example, we will create a Component to install Traefik’s Whoami service, a Tiny Go webserver that prints OS information and HTTP request headers.

In the App root directory, create directory called components and within it, a file named whoami.toml and add the following:

whoami.toml
#:schema https://api.nuon.co/v1/general/config-schema?source=helm
name           = "whoami"
type           = "helm_chart"
chart_name     = "whoami"
namespace      = "whoami"
storage_driver = "configmap"

[public_repo]
repo      = "nuonco/example-app-configs"
directory = "eks-simple/src/components/whoami"
branch    = "main"

[[values_file]]
contents = "./values/whoami.yaml"

You will also need ALB and Certificate components to expose the Whoami service to the internet.

In the components directory, create a file named alb.toml and add the following:

alb.toml
#:schema https://api.nuon.co/v1/general/config-schema?source=helm

name         = "application_load_balancer"
type         = "helm_chart"
chart_name   = "application-load-balancer"
dependencies = ["whoami"]

[public_repo]
repo      = "nuonco/components"
directory = "aws/alb"
branch    = "main"

[values]
domain_certificate = "{{.nuon.components.certificate.outputs.public_domain_certificate_arn}}"
domain             = "{{.nuon.inputs.inputs.sub_domain}}.{{.nuon.install.sandbox.outputs.nuon_dns.public_domain.name}}"
https_port         = "443"
service_name       = "whoami"
service_port       = "80"
install_name       = "{{.nuon.install.id}}"

In the components directory, create a file named certificate.toml and add the following:

certificate.toml
#:schema https://api.nuon.co/v1/general/config-schema?source=terraform

name              = "certificate"
type              = "terraform_module"
terraform_version = "1.11.3"

[public_repo]
repo      = "nuonco/example-app-configs"
directory = "eks-simple/src/components/certificate"
branch    = "main"

[vars]
install_id  = "{{ .nuon.install.id }}"
region      = "{{ .nuon.install_stack.outputs.region }}"
zone_id     = "{{ .nuon.install.sandbox.outputs.nuon_dns.public_domain.zone_id }}"
domain_name = "*.{{ .nuon.install.sandbox.outputs.nuon_dns.public_domain.name }}"

Actions

Actions are used to perform operations on your App, such as healthchecks or running kubectl commands.

In the App root directory, create directory called actions and within it, a file named simple_action.toml and add the following to create a random secret in the whoami namespace:

simple_action.toml
#:schema https://api.nuon.co/v1/general/config-schema?source=action

name    = "simple_demonstration"
timeout = "1m"

[[triggers]]
type = "post-provision"

[[triggers]]
type = "manual"

[[steps]]
name    = "create secrets in cluster"
inline_contents = """
#!/usr/bin/env sh
password=`openssl rand -hex 12`
kubectl create -n whoami secret generic whoami \
  --save-config    \
  --dry-run=client \
  --from-literal=value="$password" \
  -o yaml | kubectl apply -f -
"""

Other Configuration Files

Look at the eks-simple App Config in the example-app-configs repository for the remaining and required directory structure and files. The files created above are marked in **.

- **eks-simple**
    - **actions**
        - **simple_action.toml**
    - **components**
        - **alb.toml**
        - **certificate.toml**
        - **whoami.toml**
    - permissions 
        - deprovision_boundary.json
        - deprovision.toml
        - maintenance_boundary.json
        - maintenance.toml
        - provision_boundary.json
        - provision.toml
    - policies
        - disallow-ingress-nginx-custom-snippets.yml
        - set-karpenter-non-cpu-limits.yaml
    - src
        - components
            - whoami
                - templates
                    - deployment.yaml
                    - service.yaml
                - Chart.yaml
    - break_glass.toml
    - **inputs.toml**
    - installer.toml
    - metadata.toml
    - policies.toml
    - README.md
    - runner.toml
    - **sandbox.tfvars**
    - **sandbox.toml**
    - secrets.toml
    - stack.toml

Sync App Config to Nuon

You now have a complete Nuon App Config.

This is a good place to stop and sync it to Nuon.

Make sure you are in the root directory of your app, then run:

nuon apps sync .

Select the App in the Dashboard, and you should now see the updated Inputs, Sandbox, Components, and Runner configuration.

Create an Install

Click the Create Install button in the top right corner of the App page in the Dashboard. Give your Install a name choosethe AWS Region.

Notice the Inputs you defined in the inputs.toml file are displayed here, allowing the customer to enter their own values.

After entering the Inputs, click the Create Install button at the bottom of the page to start the Workflow including the creation of an AWS CloudFormation stack link for the customer to open in their AWS account.

Monitoring Installs

As soon as you kick off the install provisioning, you should see the new install’s workflow in the dashboard.

Create the CloudFormation Stack in AWS

Click or copy the CloudFormation link to open it in your AWS account. You will need to log in to your AWS account if you are not already logged in. This creates a VPC, required policies that Nuon expects, an Autoscaling Group, a VM with Docker and a container that installs the Nuon Build Runner in your AWS account, which will be used to provision the Install of your App. Scroll down to the bottom of the page, accept the defaults, and click the Create Stack button.

Monitor the CloudFormation Stack creation in AWS

Monitor the CloudFormation stack creation in the AWS console. This will take a few minutes to complete. You can also pull up the AWS EC2 console and see the EC2 VM appear at some point with the install Id in its name. The Nuon Dashboard will not provide feedback until the Runner is up and connected to Nuon.

Monitor the Remainder of the Install Workflow

If plan steps require approvals, you will need to approve them in the Dashboard. You can also monitor the progress of the install in the Dashboard.

In the AWS console, you can see the EKS cluster being created.

In the AWS console, you can see the Application Load Balancer being created and the Target Group being created for the Whoami service.

Inspect the Install

When the install has provisioned, and the deploys have completed, copy the install ID from the UI and curl the API to verify it’s running.

curl https://whoami.{install_id}.nuon.run

You should see a response similar to the following:

Hostname: whoami-78ffb6cbf9-rhtlb
IP: 127.0.0.1
IP: ::1
IP: 10.128.130.230
IP: fe80::1076:d7ff:fe3c:3bab
RemoteAddr: 10.128.0.10:11270
GET / HTTP/1.1
Host: whoami.inlgekffpkqv08yy8ayt7mxuyy.nuon.run
User-Agent: curl/8.7.1
Accept: */*
X-Amzn-Trace-Id: Root=1-6864407f-5e2b57f16533e41347ae8c8c
X-Forwarded-For: 136.49.24.124
X-Forwarded-Port: 443

Deprovision the Install

Nuon is mindful of your public cloud spend, so provide the following deprovisioning steps. Deprovisioning the Install is a two-step process. First, you need to deprovision the Install in the Nuon Dashboard, which will deprovision the resources to install your App. Once that is completed successfully, you then need to delete the CloudFormation stack in the AWS console, which removes the Build Runner by destroying the EC2 VM, ASG, and VPC.

Be sure to back up any data you want to keep before deprovisioning the Install, as this will delete all resources created by the Install.

Manually Deprovision the Install

If deprovisioning the Install in the Dashboard fails, there is a error-destroy.sh script in the Nuon Managed Sandboxes repository that you can use to manually deprovision the Install. This script will remove all resources created by the Install, including the EKS cluster, ALB, certificates, and Route53 DNS records.

You still have to delete the CloudFormation stack in the AWS console after running this script to remove the Build Runner, ASG, EC2 VM, and VPC.

Wrapping Up and Next Steps

Congratulations, you just deployed a BYOC app to AWS! A few suggestions for where to go next:

  • Check out our Release Management guide to learn how to update installs.
  • Dig into our App Configuration guide to learn how to configure more complex apps.
  • Share your installer with a friend and have them install your app in their AWS account.