Skip to content

Commit

Permalink
Update split the CDK stacks into back and front end
Browse files Browse the repository at this point in the history
Update the building docs
  • Loading branch information
Donal Stewart committed Jan 10, 2021
1 parent 7ed98d5 commit 18a2db9
Show file tree
Hide file tree
Showing 22 changed files with 265 additions and 23 deletions.
204 changes: 197 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
# Learning Through Landscapes - Learning and Play Audit Survey



This monorepo contains the following projects:

- [cdk-backend](cdk-backend) - AWS CDK project to build required AWS components and deploy web applications.
- [cdk-stacks](cdk-stacks) - AWS CDK project to build required AWS components and deploy web applications.
- [surveyclient](surveyclient) - React (PWA) web application for completing the LTL audit surveys.
- [adminclient](adminclient) - React web application for review and retrieval of LTL audit survey responses.
- [sharedmodel](sharedmodel) - content common to surveyclient and adminclient - the survey questions and description.

To build and deploy this application, start with building [sharedmodel](sharedmodel), then build the two web
applications [adminclient](adminclient) and [surveyclient](surveyclient), finally build the AWS CDK project
[cdk-backend](cdk-backend), as described in each project.

Built by [Scottish Tech Army](https://www.scottishtecharmy.org/) volunteers.

This project is property of [Learning Through Landscapes](https://www.ltl.org.uk/). The project code is Open Source
Expand All @@ -24,3 +18,199 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

## Building and deploying

To build the components of the application and deploy to AWS, follow these instructions after cloning the repo. The instructions are environment specific. In the instructions below, the environment being created is `dev`. Other options are `test` and `live`.

### Prerequisites

The following tools are needed in the build and deploy process, install them first

- Register or use an existing AWS account with [CLI access keys](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html).
- Install [NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm/)
- Install the [AWS CDK](https://docs.aws.amazon.com/cdk/index.html), described here: https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_install
- Install and start [Docker](https://www.docker.com/get-started) to build the Lambda functions

### Build and deploy the backend components

In the following, `PROJECT_ROOT` is the directory where you have cloned the repo.

#### Install dependencies for node projects

```
cd PROJECT_ROOT/cdk-stacks; npm install
cd resources/addSurveyLambda; npm install
cd ../confirmSurveyLambda; npm install
```

#### Deploy backend

```
cd PROJECT_ROOT/cdk-stacks
cdk deploy PREFIX-Backend-dev --profile AWS_PROFILE --context env=dev --context nameprefix=PREFIX`
```

Here `PREFIX` is the resource prefix for your deployment, e.g. '`MySurvey`'. This needs to be unique to your deployment as it is used for resource name generation and S3 resource names must be unique within their AWS region.
Use `--profile AWS_PROFILE` if necessary to choose the correct [AWS CLI access keys](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html).

The CDK will create and deploy a CloudFormation stack of the backend AWS components. If it completes successfully, it will return output like:

```
✅ PREFIX-Backend-dev
Outputs:
PREFIX-Backend-dev.LTLclientAPIendpoint = https://0000000000.execute-api.eu-west-2.amazonaws.com/prod/
PREFIX-Backend-dev.SurveyClientApiEndpointEBB28C68 = https://0000000000.execute-api.eu-west-2.amazonaws.com/prod/
PREFIX-Backend-dev.SurveyResourcesbucket = PREFIX-dev-surveyresources
PREFIX-Backend-dev.SurveyResponseSummariesindex = SummaryIndex
PREFIX-Backend-dev.SurveyResponsestable = PREFIX-dev-SurveyResponses
PREFIX-Backend-dev.Surveyadminidentitypoolid = eu-west-2:00000000-0000-0000-0000-000000000000
PREFIX-Backend-dev.Surveyadminuserpoolid = eu-west-2_000000000
PREFIX-Backend-dev.Surveyadminuserpoolwebclientid = 00000000000000000000000000
PREFIX-Backend-dev.Surveyuserpoolid = eu-west-2_000000000
PREFIX-Backend-dev.Surveyuserpoolwebclientid = 00000000000000000000000000
Stack ARN:
arn:aws:cloudformation:eu-west-2:ACCOUNT_NUMBER:stack/PREFIX-Backend-dev/00000000-0000-0000-0000-000000000000
```

These outputs are also shown in the outputs section of the CloudformationStack in the AWS Console. They are used to populate the environment specific parameters in the build of the frontend clients below.

### Build the frontend components

#### Configure environment specific settings

Copy `PROJECT_ROOT/adminclient/.env` to `PROJECT_ROOT/adminclient/.env.local` and fill in the AWS backend parameters (from the outputs above):

```
# AWS configuration
REACT_APP_DEPLOY_ENVIRONMENT=DEV
# Authentication
REACT_APP_AWS_REGION=eu-west-2
REACT_APP_AWS_IDENTITY_POOL_ID=[PREFIX-Backend-dev.Surveyadminidentitypoolid]
REACT_APP_AWS_USER_POOL_ID=[PREFIX-Backend-dev.Surveyadminuserpoolid]
REACT_APP_AWS_USER_POOL_WEB_CLIENT_ID=[PREFIX-Backend-dev.Surveyadminuserpoolwebclientid]
# Photo Storage
REACT_APP_AWS_SURVEY_RESOURCES_S3_BUCKET=[PREFIX-Backend-dev.SurveyResourcesbucket]
# Dynamo DB Table
REACT_APP_AWS_SURVEY_RESPONSES_TABLE=[PREFIX-Backend-dev.SurveyResponsestable]
REACT_APP_AWS_SURVEY_RESPONSES_SUMMARY_INDEX=SummaryIndex
```

for example:

```
# AWS configuration
REACT_APP_DEPLOY_ENVIRONMENT=DEV
# Authentication
REACT_APP_AWS_REGION=eu-west-2
REACT_APP_AWS_IDENTITY_POOL_ID=eu-west-2:00000000-0000-0000-0000-000000000000
REACT_APP_AWS_USER_POOL_ID=eu-west-2_000000000
REACT_APP_AWS_USER_POOL_WEB_CLIENT_ID=00000000000000000000000000
# Photo Storage
REACT_APP_AWS_SURVEY_RESOURCES_S3_BUCKET=PREFIX-dev-surveyresources
# Dynamo DB Table
REACT_APP_AWS_SURVEY_RESPONSES_TABLE=PREFIX-dev-SurveyResponses
REACT_APP_AWS_SURVEY_RESPONSES_SUMMARY_INDEX=SummaryIndex
```

Copy `PROJECT_ROOT/surveyclient/.env` to `PROJECT_ROOT/surveyclient/.env.local` and fill in the AWS backend parameters (from the outputs above):

```
# AWS configuration
REACT_APP_DEPLOY_ENVIRONMENT=DEV
# Authentication
REACT_APP_AWS_REGION=eu-west-2
REACT_APP_AWS_USER_POOL_ID=[PREFIX-Backend-dev.Surveyuserpoolid]
REACT_APP_AWS_USER_POOL_WEB_CLIENT_ID=[PREFIX-Backend-dev.Surveyuserpoolwebclientid]
# Survey Client API Gateway
REACT_APP_AWS_CLIENT_API_ENDPOINT=[PREFIX-Backend-dev.LTLclientAPIendpoint]
```

#### Build the shared component

Create a production build of the [sharedmodel](../sharedmodel)

```
cd PROJECT_ROOT/sharedmodel
npm install
npm run build
```

#### Build the web clients

Create a production build of the [adminclient](../adminclient)

```
cd PROJECT_ROOT/adminclient
npm install
npm run build
```

Create a production build of the [surveyclient](../surveyclient)

```
cd PROJECT_ROOT/surveyclient
npm install
npm run build
```

### Deploy the frontend components - hosted with AWS

As the two web clients are static sites, you can either deploy to AWS and direct incoming traffic to the correct CloudFront distribution, or just host them on your own websites. To deploy to AWS:

```
cd PROJECT_ROOT/cdk-stacks
cdk deploy PREFIX-Frontend-dev --profile AWS_PROFILE --context env=dev --context nameprefix=PREFIX`
```

Use the same environment and prefix as for the backend above. The CDK will create and deploy a CloudFormation stack of the frontend AWS components. If it completes successfully, it will return output like:

```
✅ LTLSurvey2-Frontend-dev
Outputs:
LTLSurvey2-Frontend-dev.AdminWebClientURL = https://0000000000000.cloudfront.net
LTLSurvey2-Frontend-dev.SurveyWebClientURL = https://0000000000000.cloudfront.net
Stack ARN:
arn:aws:cloudformation:eu-west-2:ACCOUNT_NUMBER:stack/LTLSurvey2-Frontend-dev/00000000-0000-0000-0000-000000000000
```

The web client URLs are the endpoints of the two web clients in cloudfront. These can then be set up with DNS, Route53, etc.

### or deploy the frontend components - hosted elsewhere

To host on your own website, build the web clients as described above and the copy the contents of the web client builds at `surveyclient/build` and `adminclient/build` to appropriate locations on your website.

## Building and deploying on other environments

The process is basically the same:

- Create an environment specific backend with the CDK backend stack
- Use the output to populate environment specific configuration for the web clients
- Build and deploy the frontend stack.

Multiple `.env.CONFIG` files can be maintained in the web client folders. The `package.json` of each of the web clients can be set to look for particular config files for particular builds:

```
"scripts": {
...
"build:ltltest": "env-cmd -f .env.ltltest npm run build",
"build:ltllive": "env-cmd -f .env.ltllive npm run build"
},
```

For example, `npm run build:ltltest` will create a build using the configuration in `.env.ltltest`.
10 changes: 3 additions & 7 deletions adminclient/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@
This project contains the React web application for LTL survey administration.
It was created using [Create React App](https://facebook.github.io/create-react-app/docs/getting-started).

## Prerequisites
## Building

- Install [npm]([https://docs.npmjs.com/)
- Build [sharedmodel](../sharedmodel)
- Create environment specific `.env.[ENVIRONMENT]` files by copying `.env` and filling in the missing values from the appropriate AWS deployment. See building for the first time in the [cdk-backend](../cdk-backend) documentation.
- `.env.local` - DEV environment file
- `.env.ltltest` - TEST environment file
- `.env.ltllive` - LIVE environment file
See the [monorepo build and deploy instructions](../README.md)

## Available Scripts

Expand All @@ -35,6 +30,7 @@ Builds the app for production to the `build` folder.<br />
It correctly bundles React in production mode and optimizes the build for the best performance.

Environment specific builds are available, using environment specific `.env.[ENVIRONMENT]` files (described above). To build, run:

- `npm run build` - for DEV environment
- `npm run build:ltltest` - for TEST environment
- `npm run build:ltllive` - for LIVE environment
1 change: 1 addition & 0 deletions adminclient/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "adminclient",
"version": "0.1.0",
"private": true,
"homepage": ".",
"dependencies": {
"learning-play-audit-shared": "file:../sharedmodel",
"@aws-amplify/auth": "^3.4.15",
Expand Down
2 changes: 1 addition & 1 deletion adminclient/src/SurveyResultsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ function LTLTableHead({
{ id: FIELD_CONTACT_NAME, disablePadding: false, label: "Contact Name" },
{ id: FIELD_EMAIL, disablePadding: false, label: "Email" },
{ id: FIELD_ID, disablePadding: false, label: "Id" },
{ id: FIELD_STATE, disablePadding: false, label: "State" },
{ id: FIELD_STATE, disablePadding: false, label: "Upload State" },
];

return (
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
58 changes: 58 additions & 0 deletions cdk-stacks/lib/cdk-frontend-stack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const cdk = require("@aws-cdk/core");
const { Bucket } = require("@aws-cdk/aws-s3");
const cloudfront = require("@aws-cdk/aws-cloudfront");
const origins = require("@aws-cdk/aws-cloudfront-origins");
const s3deploy = require("@aws-cdk/aws-s3-deployment");

class CdkFrontendStack extends cdk.Stack {
/**
*
* @param {cdk.Construct} scope
* @param {string} id
* @param {cdk.StackProps=} props
*/
constructor(scope, stackId, props) {
super(scope, stackId, props);

// React website hosting - survey client
addHostedWebsite(this, "SurveyWebClient", "../surveyclient/build");

// React website hosting - admin client
addHostedWebsite(this, "AdminWebClient", "../adminclient/build");

function addHostedWebsite(scope, name, pathToWebsiteContents) {
const BUCKET_NAME = name;
const DISTRIBUTION_NAME = name + "Distribution";
const DEPLOY_NAME = name + "DeployWithInvalidation";

const bucket = new Bucket(scope, BUCKET_NAME, {});

const distribution = new cloudfront.Distribution(
scope,
DISTRIBUTION_NAME,
{
defaultBehavior: {
origin: new origins.S3Origin(bucket),
allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
viewerProtocolPolicy:
cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
},
defaultRootObject: "index.html",
}
);

new s3deploy.BucketDeployment(scope, DEPLOY_NAME, {
sources: [s3deploy.Source.asset(pathToWebsiteContents)],
destinationBucket: bucket,
distribution,
});

new cdk.CfnOutput(scope, name + " URL", {
value: "https://" + distribution.domainName,
description: "External URL for " + name + " website",
});
}
}
}

module.exports = { CdkFrontendStack };
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 4 additions & 8 deletions surveyclient/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@
This project contains the React web application for the LTL survey.
It was created using [Create React App](https://facebook.github.io/create-react-app/docs/getting-started).

## Prerequisites

- Install [npm]([https://docs.npmjs.com/)
- Build [sharedmodel](../sharedmodel)
- Create environment specific `.env.[ENVIRONMENT]` files by copying `.env` and filling in the missing values from the appropriate AWS deployment. See building for the first time in the [cdk-backend](../cdk-backend) documentation.
- `.env.local` - DEV environment file
- `.env.ltltest` - TEST environment file
- `.env.ltllive` - LIVE environment file
## Building

See the [monorepo build and deploy instructions](../README.md)


## Available Scripts

Expand Down
1 change: 1 addition & 0 deletions surveyclient/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "learning-play-audit",
"version": "0.1.0",
"private": true,
"homepage": ".",
"dependencies": {
"@aws-amplify/auth": "^3.4.15",
"@aws-amplify/core": "^3.8.7",
Expand Down

0 comments on commit 18a2db9

Please sign in to comment.