Add contrib doc for AWS ECR + EKS deployment

Signed-off-by: Tim Hansen <timbonicus@gmail.com>
This commit is contained in:
Tim Hansen
2021-04-05 09:10:55 -06:00
parent f91ee28deb
commit 454002eee0
2 changed files with 196 additions and 0 deletions
+195
View File
@@ -0,0 +1,195 @@
# Deploying Backstage on AWS using ECR and EKS
Backstage documentation shows how to build a [Docker
image](https://backstage.io/docs/getting-started/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/getting-started/deployment-docker)
documentation to build a new Backstage Docker image:
```shell
$ yarn build
$ docker image build . -f packages/backend/Dockerfile --tag backstage
```
This command builds a backend-only image, but you can similarly build a frontend
or combined Docker image.
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: <access key ID>
AWS Secret Access Key: <secret access key>
Default region name: <region for your ECR repository>
```
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 <region> | docker login --username AWS --password-stdin <repo_url>
Login Succeeded
$ docker tag backstage:latest <repo_url>/backstage:latest
$ docker push <repo_url>/backstage:latest
$ docker tag backstage:latest <repo_url>/backstage:1.0.0
$ docker push <repo_url>/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, create a `kubernetes` folder in your
Backstage source folder and add a Kubernetes `deployment.yaml`:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backstage-backend
labels:
app: backstage-backend
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: backstage-backend
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: backstage-backend
spec:
containers:
- image: <repo_url>/backstage:1.0.0
imagePullPolicy: Always
name: backstage-backend
ports:
- containerPort: 7000
protocol: TCP
```
Note the `image` key in the container spec referencing the ECR repository.
Now create a simple `service.yaml` to map the container ports:
```yaml
apiVersion: v1
kind: Service
metadata:
name: backstage-backend
spec:
selector:
app: backstage-backend
ports:
- protocol: TCP
port: 80
targetPort: 7000
```
Apply these Kubernetes definitions to the EKS cluster to complete the Backstage
deployment:
```shell
$ kubectl apply -f deployment.yaml
$ kubectl apply -f 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
Backstage users need to query the backend, which means 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
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
```
### Updating the deployment
To update the Kubernetes deployment to a newly published version of your
Backstage Docker image, update the image tag reference in `deployment.yaml` and
then apply the changes to EKS with `kubectl apply -f deployment.yaml`.