# Getting Started - App Mesh

This guide covers how Argo Rollouts integrates with service-meshes managed by [AWS App Mesh](https://docs.aws.amazon.com/app-mesh/latest/userguide/what-is-app-mesh.html). This guide builds upon the concepts of the [basic getting started guide](../../getting-started.md).

## Requirements
- Kubernetes cluster with AWS App Mesh Controller for K8s installed

!!! tip

    See the [App Mesh Controler Installation instructions](https://docs.aws.amazon.com/app-mesh/latest/userguide/getting-started-kubernetes.html) on how to get started using App Mesh with Kubernetes.

## 1. Deploy the Rollout, Services, App Mesh CRD

When App Mesh is used as the traffic router, the Rollout canary strategy must define the following mandatory fields:

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-rollout
spec:
  strategy:
    canary:
      # canaryService and stableService are references to Services which the Rollout will modify
      # to target the canary ReplicaSet and stable ReplicaSet respectively (required).
      canaryService: my-svc-canary
      stableService: my-svc-stable
      trafficRouting:
        appMesh:
          # The referenced virtual-service will be used to determine the virtual-router that is
          # manipulated to update canary weights.
          virtualService:
            # name of the virtual-service App Mesh CR
            name: my-svc
            # Optional set of routes to update. If empty, all routes associated with the virtual-service are updated.
            routes:
            - http-primary
          # virtualNodeGroup is a structure to refer App Mesh virtual-node CR corresponding to Canary and Stable versions
          virtualNodeGroup:
            # canaryVirtualNodeRef refers to virtual-node corresponding to canary version. Rollouts controller will
            # update the podSelector of this virtual-node to latest canary pod-hash generated by controller.
            canaryVirtualNodeRef:
              name: my-vn-canary
            # stableVirtualNodeRef refers to virtual-node corresponding to stable version. Rollouts controller will
            # update the podSelector of this virtual-node to latest stable pod-hash generated by controller.
            stableVirtualNodeRef:
              name: my-vn-stable
      steps:
      - setWeight: 25
      - pause: {}
      ...
```

In this guide, the two services are: `my-svc-canary` and `my-svc-stable` respectively. There are two
virtual-node CRs corresponding to these services named `my-vn-canary` and `my-vn-stable`
respectively. In addition, there is a virtual-service named `rollout-demo-vsvc` that is provided by a
virtual-router CR named `rollout-demo-vrouter`. This virtual-router need have at least one route with action to forward
traffic to the canary and stable virtual-nodes. Initially weight for canary is set to 0% while for stable it is 100%.
During rollout, controller will modify the weights on route(s) based on the configuraiton defined in
`steps[N].setWeight`. 

To summarize, run the following commands to deploy a service:

* Two services (stable and canary)
* One service (for VIP and DNS lookup)
* Two App Mesh virtual-nodes (stable and canary)
* One App Mesh virtual-router with routes to virtual-nodes
* One App Mesh virtual-service corresponding to VIP service
* A rollout

```shell
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/appmesh/canary-service.yaml
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/appmesh/canary-rollout.yaml
```
## 2. Verify service

First make sure that rollout is stable.

```shell
kubectl argo rollouts get rollout my-rollout -n argo-examples -w
```

Then make sure the service is functional.

```shell
kubectl -n argo-examples port-forward svc/my-svc 8181:80
```

## 3. Rollout new version

Now its time to deploy new version. Update the rollout with new image.

```shell
kubectl argo rollouts set image my-rollout demo=argoproj/rollouts-demo:green -n argo-examples
```

Rollout should deploy a new canary revision and update the weights under virtual-router.

```shell
kubectl get -n argo-examples virtualrouter my-vrouter -o json | jq ".spec.routes[0].httpRoute.action.weightedTargets"
[
  {
    "virtualNodeRef": {
      "name": "my-vn-canary"
    },
    "weight": 25
  },
  {
    "virtualNodeRef": {
      "name": "my-vn-stable"
    },
    "weight": 75
  }
]
```

Now manually approve the rollout that is paused indefinitely, and continue watching the routes get updated

```shell
kubectl argo rollouts promote my-rollout -n argo-examples

watch -d 'kubectl get -n argo-examples virtualrouter my-vrouter -o json | jq ".spec.routes[0].httpRoute.action.weightedTargets"'
```
