engineering

Ably Engineering Team: sdk.ably.com

Introduction

A space for us to store artefacts generated by our CI workflows. This page documents how we use this space, primarily focussed on hierarchical structure (folders / S3 object prefixes).

Agreed under ADR23: Home for SDK CI/CD generated artefacts (internal).

Folder Structure

Root Folder

Initially we will have a single folder at the root of the hierarchy:

Name Public URL
builds https://sdk.ably.com/builds/

Org Root Folders

Under builds there will be a folder for each Ably GitHub Organization.

Org Name Public URL
ably https://sdk.ably.com/builds/ably/
ably-forks https://sdk.ably.com/builds/ably-forks/
ably-labs https://sdk.ably.com/builds/ably-labs/

Repository Root Folders

Under each org there will be a folder for each repository.

Org Name Repository Name Public URL
ably ably-java https://sdk.ably.com/builds/ably/ably-java/
ably-forks vcdiff-decoder https://sdk.ably.com/builds/ably-forks/vcdiff-decoder/

Default Branch Folder (main)

Under each repository there will be a folder which will always contain the latest output from the default branch (the “base”, usually called main).

Org Name Repository Name Public URL
ably ably-java https://sdk.ably.com/builds/ably/ably-java/main/

Pull Request Folders (pull)

Using the same URL structure as used by GitHub. e.g.:

Tag / Release Folders (tag)

Using a similar URL structure as used by GitHub. e.g.:

AWS Setup

All SDK AWS resources exist in the Ably SDK AWS account (see internal page for account ID).

SDK artefacts are stored in the public sdk.ably.com S3 bucket, which was created manually in the eu-west-2 region with static web hosting enabled. Basic index.html and error.html files were uploaded and configured as the index and error documents respectively. We have also uploaded a robots.txt file in order to prevent this domain from being crawled.

CloudFront distribution d1cv10k4u2d588.cloudfront.net was created with the sdk.ably.com S3 bucket as an origin, and sdk.ably.com configured as a CNAME in Cloudflare. A custom cache policy has been created and applied under the name sdk-ably-com_Low-Default-TTL, overriding the default TTL to 5 minutes which means that we don’t need to push cache control headers to S3 for individual objects.

A TLS certificate was issued in ACM for sdk.ably.com in us-east-1 using domain validation and assigned to the CloudFront distribution.

GitHub Actions AWS Access

AWS access is provided to GitHub Actions running on repositories within the ably GitHub organisation using OpenID Connect.

An AWS IAM role is created for each SDK GitHub repository which permits uploads to the sdk.ably.com S3 bucket, and that IAM role can be assumed by any GitHub Action running on the respective repository using the aws-actions/configure-aws-credentials GitHub action. This is typically used in conjunction with our own ably/sdk-upload-action GitHub action.

The AWS OIDC provider for GitHub and the AWS IAM roles are managed by Terraform within the terraform/live/ably_sdk_aws/prod directory of our internal infrastructure GitHub repository. There is a Terraform file for each repository so that permissions can evolve for each repository separately.

This step requires the terraform-docs tool. This can be installed by running:

asdf plugin-add terraform-docs https://github.com/looztra/asdf-terraform-docs

See here for further information about working with Terraform in the infrastructure repository.

To add permissions for a new SDK repository:

The ABLY_AWS_ACCOUNT_ID_SDK GitHub organization secret should be added to the SDK repository and used within the ARN passed to role-to-assume, for example (GitHub workflow step):

- name: Configure AWS Credentials
  uses: aws-actions/configure-aws-credentials@v1
  with:
    aws-region: eu-west-2
    role-to-assume: arn:aws:iam::$:role/ably-sdk-builds-THE_REPO_NAME_FROM_THE_TERRAFORM_MODULE
    role-session-name: "$-$"

If you don’t have permission to manage GitHub organization secrets, create an IT support ticket requesting it be added.

The GitHub workflow job including the aforementioned step will also need to request the id-token: write permission.

See the docs workflow in ably-flutter for a reference example.