# Ambassador

Ambassador Edge Stack is an API gateway that serves as an ingress controller into your Kubernetes cluster. Ambassador Edge Stack offers a comprehensive set of security functionality, supports a broad range of protocols, and supports progressive releases with modern traffic management. To learn more about Ambassador Edge Stack, you can read more about it [here](https://www.getambassador.io/docs/edge-stack/).

## What Will You Do

In this exercise,
- You will create an "Ambassador Edge Stack" addon and use it in a custom cluster blueprint
- You will then apply this cluster blueprint to a managed cluster

## Assumptions

- You have already provisioned or imported one or more Kubernetes clusters using the controller. You can learn more about getting started with clusters [here](https://docs.rafay.co/clusters/clusters/).

## Step 1: Add Repository To Integrations

- Navigate to the "Integrations" section and select "Repositories." Select "+ New Repository" to create a new repository
- Enter "ambassador-labs" in the "Name" section
- Select "Helm" as your "Type"
- Select "Create"
- Enter " [https://getambassador.io/](https://getambassador.io/)" in the "Endpoint" section

## Step 2: Customize Helm Install (optional)

Go to the Helm Chart [Readme](https://github.com/emissary-ingress/emissary/tree/release/v1.14/charts/ambassador) for all available Helm values. Create a `values.yaml` to customize your helm release, such as setting pod annotations or changing port values.

## Step 3: Create Namespaces

- Navigate to the "Infrastructure" section and select "Namespaces." Click on the "+ New Namespace" button to create a new namespace.
- Enter "ambassador" in the "Name" section
- For "Type" Select "Wizard" from the dropdown
- In the Pod Security Policy section, enter "rafay-privileged-psp"
- In the Description section, enter "Default namespace for Ambassador Labs products"
- Click the "SAVE" button
- Click "Save & Go To Placement"
- Set "Placement Policy" to "Specific Clusters"
- Select your cluster you want the namespace in
- Click the "Save And Go To Publish" button
- Click the "Publish" button
- Select the "New Namespace" button to create another new namespace
- Enter "quote-test" in the "Name" section
- For "Type" Select "Wizard" from the dropdown
- In the Pod Security Policy section, enter "rafay-privileged-psp"
- Click the "SAVE" button
- Click "Save & Go To Placement"
- Set "Placement Policy" to "Specific Clusters"
- Select your cluster you want the namespace in
- Click the "Save And Go To Publish" button
- Click the "Publish" button

## Step 4: Create Addon

- Navigate to the "Infrastructure" section and select "Add-Ons." Click on the "+ New Add-On" button to create a new add-on.
- Select "Bring your own"
- Enter "ambassador" in the "Name" section
- Select "Helm 3" for the "Type" section
- For "Artifact Sync," select the "Pull files from repository" option
- For "Repository Type," select the "Helm" option
- For "Namespace" Select "ambassador" from the dropdown.
- Select the "Create" button
- You will notice there is a box underneath your newly created add-on letting you know there are "No Versions Found." Click on "New Version" to add a new version of the add-on.
- Enter "edge-stack" in the "Version Name" section
- For "Repository" Select "ambassador-labs" from the dropdown
- Enter "ambassador" in the "Chart Name" section
- Enter "6.9.1" in the "Chart Version" section
- (Optional) You may upload the `values.yaml` file from Step 2 in the "Upload Files" section if you'd like to apply any changes.
- Select the "Save Changes" button

## Step 5: Create Blueprint

- Navigate to the "Infrastructure" section and select "Blueprints." Click on the "+ New Blueprint" button to create a new blueprint.
- Enter "ambassador-edge-stack" in the "Name" section
- Enter "Blueprint for Ambassador Edge Stack install" in the "Description" section
- Click "SAVE"
- You will notice there is a box underneath your newly created blueprint letting you know there are "No Versions Found." Click on "New Version" to add a new version of the blueprint
- Enter "v1.14.1" in the "Version Name" section
- Select "rafay-privileged-psp" in the "Pod Security Policies" section
- Select the "cluster-scoped" option in the "PSP Policy Type" section
- Select "Add More" in the "Add-Ons" section
- Enter "ambassador" in the "Name" section
- Enter "edge-stack" in the "Version" section
- (IMPORTANT) In the "Managed System Add-Ons" be sure to DESELECT "Ingress Controller." The rest of the options you can leave as selected.
- Select the "Save Changes" button

## Step 6: Apply Blueprint

- Navigate to the "Infrastructure" section and select "Clusters"
- Identify the cluster and Select the gear icon on the right side and select "Update Blueprint"
- Select "ambassador-edge-stack" in the "Blueprint" section
- Select "v1.14.1" in the "Version" section

## Step 7: Verify Deployment (optional)

- Remain in the "Cluster" subsection inside the "Infrastructure" section
- Select the `KUBECTL` button to open a virtual terminal
- Run `kubectl get pod -n ambassador` in your terminal
- You should see something similar to the following as output:

```
kubectl get pod -n ambassador
NAME                                READY   STATUS    RESTARTS   AGE
ambassador-agent-69979f6598-5qrk4   1/1     Running   0          3m34s
ambassador-b6fd977c7-zk5lz          1/1     Running   0          3m34s
ambassador-redis-59f894b97f-fm4zc   1/1     Running   0          3m34s
```

## Step 8: Create Workload

- To get your external IP address, run the following command:

`kubectl -n ambassador get svc ambassador -o "go-template={{range .status.loadBalancer.ingress}}{{or .ip .hostname}}{{end}}"`

- Register a DNS name for this endpoint using your preferred registrar.

- (Note) For AWS users, you may have a preconstructed hostname that was automatically generated instead of an IP address. Use a tool like `dig` (`dig <hostname> +short`) to get an IP address associated with that name.

### I Don't Have A Domain Name (optional)

[Nip.io](https://nip.io/) is a dynamic, wildcard DNS server that translates a hostname with an embedded IP address into that IP address itself.

Use the IP address obtained previously and construct a nip.io hostname. For example, if you have an IP address of 169.254.169.254, you can use 169.254.169.254.nip.io as your hostname.

- Copy and save the following code in a file with the name `quote-test.yaml`
- Replace "quote.example.com" under `hostname` with your hostname from step 8
- Replace " [my-email@datawire.io](mailto:my-email@datawire.io)" with your own email address
- Replace "quote.example.com" under `tlsSecret` with your hostname from step 8

```
---
apiVersion: getambassador.io/v2
kind: Host
metadata:
  name: quote-host
spec:
  hostname: quote.example.com # Replace with your hostname from step above.
  acmeProvider:
    authority: https://acme-v02.api.letsencrypt.org/directory
    email: my-email@datawire.io # Replace with your email
  tlsSecret:
    name: quote.example.com # Replace with your hostname from step above.
---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
  name: quote-backend
spec:
  prefix: /backend/
  service: quote
---
apiVersion: v1
kind: Service
metadata:
  name: quote
spec:
  ports:
  - name: http
    port: 80
    targetPort: 8000
  - name: https
    port: 443
    targetPort: 8000
  selector:
    app: quote
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: quote
spec:
  replicas: 1
  selector:
    matchLabels:
      app: quote
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: quote
    spec:
      containers:
      - name: backend
        image: docker.io/datawire/quote:0.4.1
        ports:
        - name: http
          containerPort: 8000
        env:
        - name: PORT
          value: "8000"
        resources:
          limits:
            cpu: "0.1"
            memory: 100Mi
```

- Navigate to the "Applications" section, and select "Workloads." Select the "+ New Workload" button to create a new workload
- Enter "quote-test-service" in the "Name" section
- Select "k8's YAML" in the "Package Type" section
- Enter "quote-test" in the "Namespace" section
- Select "Continue"
- In the "Upload Files section," select "Choose File"
- Select your `quote-test.yaml` file created previously
- Go to the "Placement" tab
- Set "Drift Action" to "NotSet"
- Set "Placement Policy" to "Specific Clusters"
- Select your cluster you want the workload in
- Select the "Publish" tab or select the "Save And Go To Publish" button
- Select the "Publish" button

## Step 9: Verify Workload

- Navigate to the "Infrastructure" section and select "Clusters"
- Click on the "Kubectl" button
- Run the command `kubectl get all -n quote-test` and verify the workload is running correctly
  - You should see something similar to the following:

```
    NAME                         READY   STATUS    RESTARTS   AGE
    pod/quote-74bd568645-dv4mw   1/1     Running   0          34m

NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
    service/quote   ClusterIP   10.100.151.122   <none>        80/TCP,443/TCP   34m

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/quote   1/1     1            1           34m

NAME                               DESIRED   CURRENT   READY   AGE
    replicaset.apps/quote-74bd568645   1         1         1       34m
    ```

## Step 10: Access Your Cluster From An External Source

Open a terminal session on your computer. Run the following command to see if you can access the quote service from your machine:

```
`curl -k https://{HOST_NAME_FROM_STEP_8}/backend/` #Replace the "{HOST_NAME_FROM_STEP_8}" with the host name received from step 8.
```

You should get an output similar to the following:

```
{
  "server": "gargantuan-raspberry-3x2rdgd8",
  "quote": "A late night does not make any sense.",
  "..."
}
```

## Recap

Congratulations! You have successfully created a custom cluster blueprint with the "Ambassador Edge Stack" addon and applied it to a cluster. You can now use this blueprint on as many clusters as you require.
