# Deploying Backstage on AWS using ECR and EKS Backstage documentation shows how to build a [Docker image](https://backstage.io/docs/deployment/docker); this tutorial shows how to deploy that Docker image to AWS using Elastic Container Registry (ECR) and Elastic Kubernetes Service (EKS). Amazon also supports deployments with Helm, covered in the [Helm Kubernetes](../../kubernetes/basic_kubernetes_example_with_helm) example. The basic workflow for this method is to build a Backstage Docker image, upload the new version to a container registry, and update a Kubernetes deployment with the new image. ## Create a container registry To create an Elastic Container Registry on AWS, go to the [AWS ECR console](https://console.aws.amazon.com/ecr/repositories). Click `Create repository` and give the repository a name, like `backstage`. ## Add an ECR IAM user To push to this new ECR repository, there must be an IAM user with `AmazonEC2ContainerRegistry` permission. Go to [AWS IAM console](https://console.aws.amazon.com/iam/home) and select `Users`. 1. Click `Add User` 2. Set the username to something like `ecr-publisher` and select `Programmatic access` only. 3. For `Permissions`, you can either create a new group or attach policies directly to the user with `AmazonEC2ContainerRegistryFullAccess`. 4. Finish creating the user; an access key ID and secret access key will be generated. ## Publish a Backstage build Follow the [Docker image](https://backstage.io/docs/deployment/docker) documentation to build a new Backstage Docker image: ```shell $ yarn build:backend $ yarn build-image --tag backstage ``` Next, configure the [AWS CLI](https://aws.amazon.com/cli/) to use the `ecr-publisher` user you created: ```shell $ aws configure AWS Access Key ID: AWS Secret Access Key: Default region name: ``` Now you can use the AWS CLI to push the built image to the ECR repository. It's a good practice to use a specific version tag as well as `latest` when pushing; more about [Semver tagging here](https://medium.com/@mccode/using-semantic-versioning-for-docker-image-tags-dfde8be06699). Go to the [AWS ECR console](https://console.aws.amazon.com/ecr/repositories) and click on your repository, then `View push commands`. This will show the repository URL to push and some sample commands. ```shell # Copy from push command window $ aws ecr get-login-password --region | docker login --username AWS --password-stdin Login Succeeded $ docker tag backstage:latest /backstage:latest $ docker push /backstage:latest $ docker tag backstage:latest /backstage:1.0.0 $ docker push /backstage:1.0.0 ``` These will take a few minutes to upload the Docker images, then you can see the image with `latest, 1.0.0` tags in the ECR repository. Now you can create a Kubernetes deployment based on this image. ## Deploy to an EKS cluster Creating an Elastic Kubernetes Service (EKS) cluster is beyond the scope of this document, but it can be as easy as `eksctl create cluster` documented in the [AWS EKS getting started guide](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html), which uses a Cloudformation template to create the necessary resources. To deploy the Docker image to EKS, follow the [Kubernetes guide](https://backstage.io/docs/deployment/k8s#creating-the-backstage-instance) but set the Backstage deployment `image` to the ECR repository URL: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: backstage namespace: backstage spec: ... template: metadata: labels: app: backstage spec: containers: - image: /backstage:1.0.0 imagePullPolicy: Always ... ``` Create the [Service descriptor](https://backstage.io/docs/deployment/k8s#creating-a-backstage-service) as well, and apply these Kubernetes definitions to the EKS cluster to complete the Backstage deployment: ```shell $ kubectl apply -f kubernetes/backstage.yaml $ kubectl apply -f kubernetes/backstage-service.yaml ``` Now you can see your Backstage workload running from the [EKS console](https://console.aws.amazon.com/eks/home). ## Further steps ### Exposing Backstage with a load balancer To make the service useful, we need to expose the workload with a load balancer. Follow the [Application load balancing on EKS](https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html) guide to set up a Load Balancer controller and Kubernetes ingress to your application. This is ultimately a `kubectl apply` with an ingress definition: ```yaml # kubernetes/backstage-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: namespace: default name: backstage-ingress annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip spec: rules: - http: paths: - path: / pathType: Prefix backend: service: name: backstage-backend port: number: 80 ```