Skip to content

Commit

Permalink
chore: update documentation for cdn host construct with example of be…
Browse files Browse the repository at this point in the history
…st practice (#85)
  • Loading branch information
malcyL authored Nov 27, 2023
1 parent e9f7837 commit bc3a840
Showing 1 changed file with 177 additions and 1 deletion.
178 changes: 177 additions & 1 deletion examples/simple-cdn-site-hosting-construct/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,183 @@ contain the additional alias.

This will require logic in both the hercules script and the projects CDK deployment code to ensure this property is set correctly.

LINK TO EXAMPLE HERE WHEN WE HAVE ONE
### Smalti Example

This is an example of the best practice described above using smalti app (i.e. the Admin UI project) as an example.

#### Hercules

The default command to deploy the smalti admin ui is

```
@hercules smalti-app deploy <environment> <region> <version>
```

e.g.

```
@hercules smalti-app deploy production eu 63-14c218fb2c88afc0905be5c4e65af7a50cfe1071
```

This deploys a new version of the smalti-app to the existing stack. This is the standard deployment which happens most of the time.

In the hercules script [here](https://github.com/talis/hercules/blob/master/scripts/smalti-app.js#L23) the watermarks of the current live stacks are
defined in the config:

```javascript
const ENVIRONMENT_CONFIGS = {
staging: {
eu: {
circleciDeployContext: CIRCLECI_CONTEXT_CDK_DEPLOY_TO_SHARED_ASPIRE,
circleciRegionContext: CIRCLECI_CONTEXT_AWS_REGION_EU,
appEnvironment: "staging-eu",
releaseWatermark: "231114",
},
},
production: {
eu: {
circleciDeployContext: CIRCLECI_CONTEXT_CDK_DEPLOY_TO_DEVOPS_ASPIRE,
circleciRegionContext: CIRCLECI_CONTEXT_AWS_REGION_EU,
appEnvironment: "production-eu",
releaseWatermark: "231115",
},
ca: {
circleciDeployContext: CIRCLECI_CONTEXT_CDK_DEPLOY_TO_DEVOPS_ASPIRE,
circleciRegionContext: CIRCLECI_CONTEXT_AWS_REGION_CA,
appEnvironment: "production-ca",
releaseWatermark: "231115",
},
},
};
```

Hercules passes this default `releaseWatermark` to circle which will deploy the new version to the stack with that watermark. The existing
stack is named `production-eu-231115-smalti-app`,

This is done [here](https://github.com/talis/hercules/blob/master/scripts/smalti-app.js#L112):

```
const parameters = {
is_deploy: true,
release_version: version,
app_environment: ENVIRONMENT_CONFIGS[environment][region].appEnvironment,
release_app_watermark: releaseWatermark.trim(),
web_host: `http://${ENVIRONMENT_CONFIGS[environment][region].appEnvironment}-${releaseWatermark.trim()}-lti-admin.talis.io/`,
api_host: `https://${ENVIRONMENT_CONFIGS[environment][region].appEnvironment}-lti.talis.io/`,
is_live: releaseWatermark.trim() === ENVIRONMENT_CONFIGS[environment][region].releaseWatermark,
slack_user: res.message.user.id,
aws_deploy_context:
ENVIRONMENT_CONFIGS[environment][region].circleciDeployContext,
aws_region_context:
ENVIRONMENT_CONFIGS[environment][region].circleciRegionContext,
};
circleciV2Api
.triggerANewPipeline(repository, 'main', parameters)
```

But in the `parameters`, in addition to the `release_app_watermark` is a flag `is_live`.

`is_live` is set to true because the `release_app_watermark` we are using is the watermark of the currently live stack:

```
is_live: releaseWatermark.trim() === ENVIRONMENT_CONFIGS[environment][region].releaseWatermark,
```

However, when creating a new stack alongside a currently live stack, the hercules command used for the deployment is:

```
@hercules smalti-app deploy <environment> <region> <version> [<watermark>]
```

e.g.

```
@hercules smalti-app deploy production eu 63-14c218fb2c88afc0905be5c4e65af7a50cfe1071 231124
```

This results in a new stack being created alongside the existing live one. The two stacks in production would be:

- `production-eu-231115-smalti-app`
- `production-eu-231124-smalti-app`

The `is_live` flag passed to circle by hercules, is set to false - because the watermark is not the watermark from the config:

```
is_live: releaseWatermark.trim() === ENVIRONMENT_CONFIGS[environment][region].releaseWatermark,
```

#### Circle

The circle build is passed an `is_live` flag from hercules.

All the circle build does with this flag is pass it to the CDK code via an environment variable [here](https://github.com/talis/smalti-app/blob/main/.circleci/config.yml#L67).

```
steps:
- run:
name: Export AWS/CDK environment variables
command: |
echo "export AWS_ACCESS_KEY_ID=${<< parameters.aws_access_key_id >>}" >> $BASH_ENV
echo "export AWS_DEFAULT_REGION=${<< parameters.aws_default_region >>}" >> $BASH_ENV
echo "export AWS_SECRET_ACCESS_KEY=${<< parameters.aws_secret_access_key >>}" >> $BASH_ENV
echo "export WATERMARK=<< parameters.release_app_watermark >>" >> $BASH_ENV
echo "export AWS_PREFIX=<< parameters.app_environment >>-<< parameters.release_app_watermark >>-" >> $BASH_ENV
echo "export RELEASE_IDENTIFIER=<< parameters.release_version >>" >> $BASH_ENV
echo "export WEB_HOST=<< parameters.web_host >>" >> $BASH_ENV
echo "export API_HOST=<< parameters.api_host >>" >> $BASH_ENV
echo "export APP_ENVIRONMENT=<< parameters.app_environment >>" >> $BASH_ENV
echo "export IS_LIVE=<< parameters.is_live >>" >> $BASH_ENV
source $BASH_ENV
```

#### CDK

The CDK code reads the `is_live` value [here](https://github.com/talis/smalti-app/blob/main/infra/bin/smalti-app.ts#L44):

```
const isLive = process.env.IS_LIVE === 'true' ? true : false;
```

and then uses it to either set or not set the `aliasSubdomain` for the stack, depending on whether it is live or not:

```
const productionEuConfig: SmaltiAppStackProps = {
prefix,
release,
app: APP_NAME,
deploymentEnvironment: TalisDeploymentEnvironment.PRODUCTION,
env: {
account: PRODUCTION_ACCOUNT_ID,
region: TalisRegion.EU,
},
tags: { env: TalisDeploymentEnvironment.PRODUCTION },
domainName: `talis.com`,
subDomain: `${prefix}lti-admin`,
aliasSubDomains: isLive ? ['lti-admin.talis.com'] : [],
assetPath: path.join(__dirname, '../../dist'),
certificateArn: PRODUCTION_EU_CLOUDFRONT_TALIS_TLS_CERT_ARN,
};
```

Specifically here:

```
aliasSubDomains: isLive ? ['lti-admin.talis.com'] : [],
```

This means that:

- live stacks will have the `aliasSubdomains` set. Repeated deployments will not delete it.
- new deployments, with a new watermark will not have any `aliasSubDomains` set. This is what we want. They can not exist in two places at once and have to be moved at the time of making the new stack live.

#### Post Making The New Stack Live

After making the new stack live, it is already our process to update the live watermark in the hercules script to the new value.

If this were not done, future standard releases would bring up the old stack again.

Having done this, future deployments to the new stack, `231124` in our example, will have the `is_live` flag set and will continue as normal.

## Useful commands

Expand Down

0 comments on commit bc3a840

Please sign in to comment.