Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: update documentation for cdn host construct with example of best practice #85

Merged
merged 2 commits into from
Nov 27, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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