AWS Open Source Blog

Building Developer Portals with Backstage and Amazon EKS Blueprints

The complexities of contemporary software development environments have led, in recent years, to the creation and adoption of Internal Developer Platforms (IDPs). IDPs’ purpose is to decrease the cognitive load for software developers, who have to use a large number of tools and products to perform their jobs. Such fragmentation causes time consuming context switches and steepens the learning curve for new joiners. IDPs address those drawbacks by providing a unified front-end, where the different tools and products are glued together and made available to the developer in a single catalog.

Backstage is a Developer Portal (DP), incepted at Spotify and open sourced in March 2020. DPs serve as the user interface to explore and access IDPs capabilities. As a DP, Backstage centralizes the different types of entities within your company, e.g.: APIs, resources, users, teams, documentation, etc. It also features an extensible architecture where additional third-party components can be plugged in and consumed in the same context, like for example AWS’s Proton plugin. Amazon EKS Blueprints for CDK (referred to as Amazon EKS Blueprints, in the rest of the post) is a set of Infrastructure as Code (IaC) modules that helps you bootstrap complete Amazon Elastic Kubernetes Service (Amazon EKS) clusters, across accounts and regions, quickly and with minimal code. Initially developed at AWS, it was open sourced in April 2022. Add-ons are Amazon EKS Blueprint’s constructs, to help you manage Kubernetes add-ons, that run within the context of a cluster.

This post shows you how to install and configure the Backstage add-on for Amazon EKS Blueprints, with the help of Amazon EKS Blueprints Patterns. The add-on will effectively allow you to install the Backstage application on your newly deployed Amazon EKS cluster. You will be able to access Backstage via an Amazon Elastic Load Balancer (Amazon ELB). This post does not address a tighter integration between Amazon EKS Blueprints and Backstage, e.g. to display and control environments, status of the pipeline, teams onboarding, etc., which is the subject of future development.

Solution overview

The following diagram shows the complete solution that I will walk you through in this post:

Backstage diagram

You will need a pre-built Docker image of Backstage, configured as you see fit, e.g., with the plugins of your choice. You can see technical details on how to accomplish this step and the next ones, in the later “Deploy Backstage” section of this post.

The Backstage pattern will then:

  • deploy this image in a new Amazon EKS cluster
  • create a new Amazon Relational Database Service (Amazon RDS) for PostgreSQL instance in the Amazon EKS cluster’s VPC
  • set up the credentials of the database above as a secret in AWS Secrets Manager
  • create an External Secret reflecting the database credentials
  • create a Kubernetes Secret from the External Secret, to be loaded by Backstage as environment variables $POSTGRES_USER and $POSTGRES_PASSWORD
  • install the AWS Load Balancer Controller add-on, which will deploy an Application Load Balancer (ALB), implementing the rules listed in Backstage Helm chart Ingress
  • create a certificate for the ALB

Prerequisites

You will need the following to complete the steps in this post:

You will also need a domain name, held within one of your Amazon Route 53’s public hosted zones, similar to the AWS Management Console image shown here:

Hosted Zones screenshot

Clone Amazon EKS Blueprints Patterns

Open your favorite command-line interface (CLI) and clone the EKS Blueprints Patterns GitHub repository:

$ git clone https://github.com/aws-samples/cdk-eks-blueprints-patterns.git

Deploy Backstage

Follow the instructions from the Backstage file within the docs folder in the EKS Blueprints Patterns repository. Here is a summary of the steps you need to take:

  1. Create the Backstage application and build the Docker image
  2. Create an Amazon Elastic Container Registry (Amazon ECR) and repository
  3. Upload the Docker image to the newly created repository
  4. Set account and region as part of your AWS CLI profile and enter the necessary parameters in the CDK context:
Parameter Description
backstage.namespace.name Kubernetes namespace to deploy Backstage, e.g. “backstage”
backstage.image.registry.name Your Image Registry, e.g. Amazon Elastic Container Registry (ECR): “{account}.dkr.ecr.{region}.amazonaws.com”,
backstage.image.repository.name The repository in the registry above, e.g.: “backstage”
backstage.image.tag.name The tag of your Backstage image, e.g.: “latest”
backstage.parent.domain.name Your domain name, under which a subdomain and related certificate will be created, e.g.: “example.com”
backstage.subdomain.label The label which will be used to create the subdomain to assign to Backstage, e.g.: “backstage”; the final subdomain will then be e.g.: “backstage.example.com”
backstage.hosted.zone.id The 20-chars long string, representing the Hosted Zone in Route 53, holding your domain name
backstage.certificate.resource.name The name to be assigned to your certificate resource, e.g.: “backstage-certificate”
backstage.database.resource.name The name to be assigned to your database resource, e.g.: “backstage-database “
backstage.database.instance.port The port to be assigned to the new Backstage database, e.g.: 5432
backstage.database.secret.resource.name The name to be assigned to the Secret resource (this is used as a reference within the CDK), e.g.: “backstage-database-credentials”
backstage.database.username The database username, e.g.: “postgres”
backstage.database.secret.target.name The name to be assigned to the Secret in the Kubernetes manifest, e.g.: “backstage-database-secret”
  1. Deploy as explained in the Amazon EKS Blueprints Patterns documentation.
$ make deps 
$ npm i
$ make build
$ make pattern backstage deploy

Finally, in a web browser, navigate to {"parent.domain.name"}.{"subdomain.label"}. You will see a screen similar to the following, depending on your Backstage application configuration:

Backstage company catalog

Code analysis

Flow diagram

It is important to note that the actual Backstage add-on is hosted under the Amazon EKS Blueprints repository, while the Backstage pattern, which demonstrates how to configure the add-on and deploy the required resources, is hosted under the Amazon EKS Blueprints Patterns repository.

The add-on relies on the Backstage Helm chart, publicly hosted on GitHub, where you can find a detailed explanation of the chart values.

Through the values, we need to configure the Helm chart as follows:

  • Set the Ingress parameters
  • Provide the Backstage application’s Docker image coordinates
  • Pass to the Backstage application:
    • the subdomain we intend to assign
    • the database endpoint and the environment variables, which will later be set to the database credentials values
    • the Secret name, holding the actual database credentials values

The Ingress most notable configuration is the Certificate Amazon Resource Name (ARN).

We are using PostgreSQL, as opposed to the default in-memory SQLite database, to achieve better scalability, concurrency, centralization, and control (access the Backstage guide for further details). Its credentials are injected in the Backstage application pods via environment variables, pulled from the Secret. The chart sources the information about the Secret name from the backstage.extraEnvVarsSecrets value, and sets that into the envFrom section of the Kubernetes Deployment manifest:

kind: Deployment
…
containers:
…
          envFrom:
            {{- range .Values.backstage.extraEnvVarsSecrets }}
…

Hence, the parameters expected by the add-on, are:

subdomain: string,
certificateResourceName: string,
imageRegistry: string,
imageRepository: string,
imageTag?: string,
databaseResourceName: string,
databaseSecretTargetName: string

The pattern provides the dependencies of the add-on.

A Resource Provider (DatabaseInstanceCredentialsProvider) creates and stores the database credentials in AWS Secrets Manager (ASM).

A second Resource Provider (DatabaseInstanceProvider) creates an Amazon RDS for PostgreSQL database instance within the cluster VPC, grabs the ASM’s secret name from the context and passes that to the database, on creation.

An add-on (BackstageSecretAddOn), leveraging the External Secrets Add-On, creates a ClusterSecretStore object, pointing to ASM, and an ExternalSecret, which pulls the credentials from ASM, and injects them in a new Kubernetes Secret, with keys POSTGRES_USER and POSTGRES_PASSWORD:

…
data: [
    {
        secretKey: "POSTGRES_PASSWORD",
        remoteRef: {
            key: databaseInstanceCredentialsSecretName,
            property:  "password"
        }
    },
    {
        secretKey: "POSTGRES_USER",
        remoteRef: {
            key: databaseInstanceCredentialsSecretName,
            property:  "username"
        }
    },
],
…

Like we explained previously, the credentials held within the Secret are then passed to the pods as environment variables $POSTGRES_USER and $POSTGRES_PASSWORD.

A third Resource Provider (CreateCertificateProvider) creates the subdomain in the Amazon Route 53 Hosted Zone and the related certificate in AWS Certificate Manager (ACM):

blueprints.EksBlueprint.builder()

.resourceProvider(blueprints.GlobalResources.HostedZone, new blueprints.ImportHostedZoneProvider(props.hostedZoneId, props.parentDomain))

.resourceProvider(props.certificateResourceName, new blueprints.CreateCertificateProvider("elb-certificate", subdomain, blueprints.GlobalResources.HostedZone))

The certificate is then grabbed by the Backstage add-on from the context, its ARN extracted…

const annotations = {
    …
    "alb.ingress.kubernetes.io/certificate-arn": clusterInfo.getResource<ICertificate>(helmOptions.certificateResourceName)?.certificateArn
};

… and assigned to the Ingress:

setPath(values, "ingress.annotations", annotations);

In the Route 53 section of the AWS Management Console, the new subdomain records will be shown, similar to this screenshot:

AWS Management Console screenshot

The certificate will appear in the AWS Certificate Manager section:

AWS Certificate manager section screenshot

What can I do now?

Backstage provides a single pane of glass to view your organization’s resources, regardless of their location, as well as a simple way to onboard and start using development tools. It also enables you to create new resources such as backend and frontend applications more easily, from within its portal.

Now that you have your Developer Platform setup, you can take advantage of those benefits and start by creating a Software Catalog. A Software Catalog allows you to keep track of ownership and metadata for all of the software in your environment (services, websites, libraries, pipelines, etc.) in a centralized place. The catalog is created from metadata YAML files stored in source control, which are registered in Backstage in various ways, and presented to the developer in a comprehensive view.

Another feature you might want to explore is Software Templates, which enable Engineering teams to build components, quickly create new projects aligned with the team’s best practices. This helps them avoid having to reinvent the wheel, have fewer decisions to make, and enables them to focus more on core activities. Software Templates are fundamental to the concept of Golden Paths, which are opinionated and supported ways to build something (for example, a backend service, a web application or a CI/CD pipeline). Rather than legislating conventions and standards, with Golden Paths, you can make it easy for teams to start new projects on the right foot.

A further example of what you can do is building documentation with TechDocs. This allows you to write markdown files that are stored in the same location as the code they are related to. Those files are then cleanly and clearly displayed in Backstage.

Please refer to the Backstage website for detailed documentation and examples of features and use cases.

Cleaning up

To avoid incurring future charges, please run the make pattern backstage destroy command.

Conclusion

In this post, I have shown how you can use the Backstage add-on from Amazon EKS Blueprints and the Backstage pattern from Amazon EKS Blueprints Patterns, to deploy a pre-built and pre-configured Backstage application. I explained the pattern’s configuration parameters, and how the pattern wires together resource providers and other add-ons to achieve a complete solution running Backstage with its dependencies.

Riccardo Freschi

Riccardo Freschi

Riccardo Freschi is a Sr. Solutions Architect at AWS, focusing on Application Modernization. He works closely with partners and customers, to help them transform their IT landscapes in their journey to the AWS Cloud, by refactoring existing applications and building new ones, cloud natively.