> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nuon.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Create an AWS EKS App

> Learn how to package and deploy a Helm app to AWS EKS.

<Note>
  This [app](/concepts/apps) can be found in the [eks-simple directory](https://github.com/nuonco/example-app-configs/tree/main/eks-simple) of the example-app-configs repository.
</Note>

## Prerequisites

* [Signup for the self-service free trial](https://app.nuon.co). You will need a login and an org in Nuon's cloud.
* [Set up an AWS account](https://docs.aws.amazon.com/SetUp/latest/UserGuide/setup-overview.html).
  This is the account you will install the app in.

## What You Will Create

This tutorial will walk you through creating the following:

* An [App](/concepts/apps)
* A [Whoami component](/concepts/components)
* An [Install](/concepts/installs), using our
  [AWS EKS sandbox](/concepts/sandboxes#nuon-managed-sandboxes)

<Note>
  We recommend you clone the [`example-app-configs`
  repository](https://github.com/nuonco/example-app-configs) which includes the
  `eks-simple` app versus creating each config file manually. This guide is
  meant to explain the concepts behind some of the config files, so you can
  create your own apps in the future.
</Note>

## 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

Clone the `example-app-configs` repository, cd into the `eks-simple` directory,
and create the app in Nuon. This will create the app in `app.nuon.co`

```sh theme={null}
git clone https://github.com/nuonco/example-app-configs
cd example-app-configs/eks-simple
nuon auth login
nuon orgs select
nuon apps create -n eks-simple
```

You should see the new app in the dashboard.

<img src="https://mintcdn.com/nuoninc/_kMmIa3KI58brGSH/images/get-started/create-your-first-app/tutorial-2.jpeg?fit=max&auto=format&n=_kMmIa3KI58brGSH&q=85&s=6a003a3d14a04b092e3fea838a02c5b1" alt="App List" width="1308" height="702" data-path="images/get-started/create-your-first-app/tutorial-2.jpeg" />

### 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.
Inputs are optional.

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

```toml inputs.toml theme={null}
# inputs
[[group]]
name         = "dns"
description  = "DNS Configrations"
display_name = "Configurations for the root domain for Route53"

[[input]]
name         = "domain"
description  = "domain for the whoami endpoint e.g., nuon.run"
default      = "nuon.run"
display_name = "Domain"
group        = "dns"

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

```

This Input defines a domain, which will default to nuon.run and 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. The subdomain will default to `whoami`, but the customer can change it to
whatever they want.

### Sandbox

Nuon provides a set of
[Nuon Managed Sandboxes](/concepts/sandboxes#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:

```toml sandbox.toml theme={null}
# sandbox
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.inputs.inputs.domain}}"
internal_root_domain = "internal.{{ .nuon.install.id }}.{{.nuon.inputs.inputs.domain}}"

[[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:

```hcl sandbox.tfvars theme={null}
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_size = 2
```

### 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 deploy Traefik's
[Whoami](https://github.com/traefik/whoami) service with Helm. Whoami is 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:

```toml whoami.toml theme={null}
# 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:

```toml alb.toml theme={null}
# 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:

```toml certificate.toml theme={null}
# 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](/concepts/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, two
actions. Create a file named `healthcheck.toml` and add the following to check
the ALB status. See the eks-simple directory of the example repo for the `healthcheck.sh` script referenced below.

```toml healthcheck.toml theme={null}
# action
name    = "alb_healthcheck"
timeout = "30s"

[[triggers]]
type = "manual"

[[steps]]
name    = "alb-healthcheck"
command = "./healthcheck.sh"

[steps.public_repo]
repo      = "nuonco/example-app-configs"
directory = "eks-simple/src/actions/alb"
branch    = "main"

[steps.env_vars]
INGRESS_NAME      = "{{.nuon.install.id}}-public"
INGRESS_NAMESPACE = "whoami"
```

### Other Configuration Files

Look at the `eks-simple` app in the
[`example-app-configs` repository](https://github.com/nuonco/example-app-configs)
for the remaining and required directory structure and files. The files created
above are marked in \*\*.

```
- **eks-simple**
    - **actions**
        - **healthcheck.toml**
        - **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 to Nuon

You now have a complete Nuon app.

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:

```sh theme={null}
nuon apps sync 
```

Select the app in the dashboard, and you should now see the updated inputs,
sandbox, components, and runner configuration.

<img src="https://mintcdn.com/nuoninc/_kMmIa3KI58brGSH/images/get-started/create-your-first-app/tutorial-3.jpeg?fit=max&auto=format&n=_kMmIa3KI58brGSH&q=85&s=c6daf26c9498ad9d3261182bf015e877" alt="App" width="1448" height="701" data-path="images/get-started/create-your-first-app/tutorial-3.jpeg" />

## 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. The provision workflow generates two install stack
formats — a CloudFormation Quick-Create / CLI snippet, and a Terraform
`install.tfvars` for the [`install-stacks/aws`](https://github.com/nuonco/install-stacks)
module — so the customer can apply whichever fits their tooling.

<img src="https://mintcdn.com/nuoninc/_kMmIa3KI58brGSH/images/get-started/create-your-first-app/tutorial-4.jpeg?fit=max&auto=format&n=_kMmIa3KI58brGSH&q=85&s=40d5ba58f4b609279a5af8113c2216ef" alt="Create Install" width="912" height="595" data-path="images/get-started/create-your-first-app/tutorial-4.jpeg" />

### Monitoring Installs

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

<img src="https://mintcdn.com/nuoninc/_kMmIa3KI58brGSH/images/get-started/create-your-first-app/tutorial-9.jpeg?fit=max&auto=format&n=_kMmIa3KI58brGSH&q=85&s=5f6342aded4a29c2cbce763eb80d2c93" alt="Install List" width="1448" height="812" data-path="images/get-started/create-your-first-app/tutorial-9.jpeg" />

### Apply the Install Stack in AWS

Apply the install stack using whichever format fits your workflow. Either way,
the resulting resources are the same: a VPC, the IAM policies Nuon expects, an
Autoscaling Group, and a VM running the Nuon Build Runner that will provision
the install of your app.

#### Option A: CloudFormation

Click or copy the CloudFormation Quick-Create link to open it in your AWS
account, log in, scroll to the bottom, accept the defaults, and click **Create
Stack**.

<img src="https://mintcdn.com/nuoninc/_kMmIa3KI58brGSH/images/get-started/create-your-first-app/tutorial-7.jpeg?fit=max&auto=format&n=_kMmIa3KI58brGSH&q=85&s=84d492dd241b7872124bd733f53fc478" alt="CloudFormation Stack" width="1447" height="923" data-path="images/get-started/create-your-first-app/tutorial-7.jpeg" />

#### Option B: Terraform

Download the generated `install.tfvars` from the dashboard, set up a `backend.tf`
(snippet provided in the dashboard), and run:

```sh theme={null}
terraform init
terraform apply -var-file=install.tfvars
```

against the [`install-stacks/aws`](https://github.com/nuonco/install-stacks) module.

### Monitor the Install Stack creation in AWS

Monitor the stack creation in the AWS console (CloudFormation) or the Terraform
output. This takes a few minutes to complete. You can also pull up the AWS EC2
console and see the EC2 VM appear with the install id in its name.
The Nuon Dashboard will not provide feedback until the runner is up and
connected to Nuon.

<img src="https://mintcdn.com/nuoninc/_kMmIa3KI58brGSH/images/get-started/create-your-first-app/tutorial-8.jpeg?fit=max&auto=format&n=_kMmIa3KI58brGSH&q=85&s=1b0a4fcfab4ff1fe2b9daaefb60734b1" alt="Stack Log" width="1492" height="923" data-path="images/get-started/create-your-first-app/tutorial-8.jpeg" />

### 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.

<img src="https://mintcdn.com/nuoninc/_kMmIa3KI58brGSH/images/get-started/create-your-first-app/tutorial-10.jpeg?fit=max&auto=format&n=_kMmIa3KI58brGSH&q=85&s=dd31347298bb2958e9d508e942575841" alt="Workflow" width="1458" height="860" data-path="images/get-started/create-your-first-app/tutorial-10.jpeg" />

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

<img src="https://mintcdn.com/nuoninc/_kMmIa3KI58brGSH/images/get-started/create-your-first-app/tutorial-11.jpeg?fit=max&auto=format&n=_kMmIa3KI58brGSH&q=85&s=6f3b827c2a7dbe191384b847102f16fb" alt="Cluster" width="1179" height="565" data-path="images/get-started/create-your-first-app/tutorial-11.jpeg" />

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

<img src="https://mintcdn.com/nuoninc/_kMmIa3KI58brGSH/images/get-started/create-your-first-app/tutorial-12.jpeg?fit=max&auto=format&n=_kMmIa3KI58brGSH&q=85&s=c3793bfae42d8f73a820ca795f5df8d9" alt="ALB" width="1229" height="573" data-path="images/get-started/create-your-first-app/tutorial-12.jpeg" />

### Inspect the Install

When the install has provisioned, and the deploys have completed, click the URL
link in the install's README.md visible on the install page in the dashboard.
Alternatively, copy the link and open a terminal and curl the API to verify it's
running.

```sh theme={null}
curl https://whoami.{install_id}.nuon.run
```

You should see a response similar to the following:

```bash theme={null}
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 we 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, tear down the install stack — delete the CloudFormation stack in
the AWS console, or run `terraform destroy` against the install module — to
remove the Build Runner by destroying the EC2 VM, ASG, and VPC.

<Note>
  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.
</Note>

## Manually Deprovision the Install

If deprovisioning the install in the dashboard fails, there is a
`error-destroy.sh` script in the
[Nuon Managed Sandboxes](/concepts/sandboxes#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.

<Note>
  You still have to tear down the install stack — delete the CloudFormation
  stack in the AWS console, or run `terraform destroy` against the install
  module — after running this script to remove the runner, ASG, EC2 VM, and VPC.
</Note>

## Wrapping Up and Next Steps

Congratulations, you just deployed an app to AWS!

A few suggestions for where to go next:

* Review other example apps in the
  [example-app-configs repository](https://github.com/nuonco/example-app-configs)
  to see how to deploy a more complex app.

* Dig into our [app](/concepts/apps) guide to learn how to configure more
  complex apps.
