- AWS Setup Instructions
- 1. Installing AWS CLI
- 2. Setting Up VPC
- 3. Setting up AWS Amplify
- 4. Install the AWS SAM CLI
- 5. Update the SAM YAML
These instructions will show you how to set up the AWS backend infrastructure for this application.
Once the backend is deployed and configured, you can run the app locally by running npm run dev from the /speedbands directory.
For information on actually building and deploying the frontend app, see this site
These instructions assume you already have the following:
- An AWS account created in your desired region.
- Are starting from a fresh AWS account with no existing changes.
- Follow these instructions to setup the Amplify CLI. This will also walk you through creating an access key. Make sure you save your access key locally, as it will be used below.
- After you've created an amplify-dev IAM user, add the
AdministratorAccesspermission to them, so you can deploy the cloud resources using SAM.Note:
AdministratorAccessis an all-encompassing policy that will allow you every permission. It is very unsecure to use this, so I highly reccommend you either add specific necessary policies, use user groups, or remove theAdministratorAccesspolicy once you've finished following these instructions. - Follow these instructions to install the AWS CLI.
- When complete, run
aws configure- Enter the access key and secret that you obtained in step 1
- Choose your region name (e.g 'ap-southeast-1`)
- Set output format to 'json'
- Test your configuration by running
aws sts get-caller-identity- Your account information should be returned:
{ "UserId": "AIDAxxxxxxxxxxxxx", "Account": "123456789012", "Arn": "arn:aws:iam::123456789012:user/YourUserName" }
In order for the Lambda functions to be able to talk to both DynamoDB and the internet, you need to set up some subnets, route tables and a NAT gateway in the VPC.
- On the AWS dashboard, navigate to VPC
- Navigate to "Subnets"
- Click "Create subnet"
- Under "VPC ID", select the only option which should be your default VPC
- Set subnet name to
lambda-subnet-point-to-nat-1 - If "IPv4 VPC CIDR block" is
X.X.0.0/16for example, set "IPv4 subnet CIDR block" toX.X.64.0/20 - Leave other settings at default
- At the bottom, click "Add new subnet"
- Repeat steps 5 to 8 until you have three subnets,
lambda-subnet-point-to-nat-[1/2/3]with subnet CIDR blocksX.X.[64/80/96].0/20 - Add one more subnet, named
lambda-subnet-point-to-igw(igw = internet gateway) - Set its CIDR block to
X.X.112.0/20
- On the AWS dashboard, navigate to VPC
- Navigate to "NAT Gateways"
- Click "Create NAT gateway"
- Under "Subnet", select
lambda-subnet-point-to-igw - Click "Allocate Elastic IP"
- Click "Create NAT gateway"
- On the AWS dashboard, navigate to VPC
- Navigate to "Route Tables"
- Click "Create route table"
- Name it
lambda-rt-to-nat - Under "VPC ID", select your default VPC
- Click "Create table"
- On the "Routes" table, click "Edit routes"
- Click "Add route"
- Under "Destination" select "0.0.0.0/0"
- Under "Target" select "NAT Gateway" and then select the gateway you created above (
nat-xxxxxxx) - Click "Save changes"
- Repeat steps 3 to 11, creating a second table named
lambda-rt-to-igw, assigning the new route's target to "Internet Gateway", and selecting the only available (default) option (igw-xxxxxxx)
- On the AWS dashboard, navigate to VPC
- Navigate to "Subnets"
- Select
lambda-subnet-point-to-nat-1 - Click "Actions"
- Click "Edit route table association"
- Under "Route Table ID", select "lambda-rt-to-nat"
- Click "Save"
- Repeat steps 3 to 7 for
lambda-subnet-point-to-nat-2 and 3.
AWS Amplify is used to provide user authentication for the frontend. Below are the instructions to configure it.
- Under
/speedbandsin this repo, delete theamplifyfolder. We will create a new Amplify setup configured to you. - In the
/speedbandsdirectory, runamplify initand use the following options:- Choose to use the Amplify Gen 1 CLI
- Name: Enter a name for the project, e.g "speedbands"
- Environment: Name your environment (e.g., prod)
- Default editor: Choose your code editor
- App type: Select JavaScript
- Framework: Choose Next.js
- Source and build settings: Use the defaults
- Region: Choose your aws region, e.g "ap-southeast-1"
- Hosting: Skip this
- Address any other options that arise (they may be different to above)
- Run
amplify add auth- Select "Default configuration"
- Choose "Email" as the sign in method.
- You may use other authentication options if you desire, but you would need to change the frontend to accomodate it.
- Run
amplify pushwhich will build the necessary resources for auth in the cloud.
Follow these instructions to install the CLI on your machine.
The template.yaml file in this repo under /backend will allow you to deploy the necessary infrastructure to AWS with a few commands using AWS' Serverless Application Model. In order to configure it to work with your AWS account, however, we need to update a few fields.
- On the AWS dashboard, navigate to VPC
- Navigate to "Subnets"
- Copy and save the Subnet IDs for
lambda-subnet-point-to-nat-1, 2 and 3. - Navigate to Security groups
- Copy and save the Security group ID for your default (only) security group.
- Open
template.yaml - Under
JobSchedulerLambda,JobCheckerLambda,DataCollectionLambdaandGetUserJobsLambda, replace the existingSubnetIdswith the three you saved above, and replace theSecurityGroupIdswith the one you saved above.
First, ensure you have the same version of Python (3.10 at time of writing) as in the YAML file installed on your machine and in your PATH. The version can be seen after Runtime: in the Lambda function definitions.
If it's your first time doing this step, run:
sam build
sam deploy --guidedIf you've already built but for whatever reason need to do it again, run the following command if the DynamoDB table DataCollectionJobs or s3 bucket for results already exists:
sam build
sam deploy --parameter-overrides TableAlreadyExists=true ResultsBucketAlreadyExists=trueThis is because the DynamoDB table and S3 bucket have DeletionPolicy set to Retain which means they aren't deleted in the event of a failure or re-deploy. This is so we don't lose the data inside them.
If, for whatever reason, deployment fails, you will need to manually navigate to the AWS CloudFormation dashboard and delete the stack which is in state ROLLBACK_COMPLETED before you can deploy another stack with the same name.
Note: If at any point you have to re-deploy the resources, you must also redploy the API Gateway API via the AWS dashboard, or any changes won't take effect.
We need to attach some permissions to the default Identity Pool IAM role that was created when we set up Amplify.
- In the AWS dashboard, navigate to IAM > Roles
- Select the role that has
amplifyandauthRolein the title. - Click Add permissions > Attach policies
- Attach the "AmazonAPIGatewayInvokeFullAccess" policy. Note: This may be unsafe if you plan on adding more infrastructure to your app and more endpoints. I recommend you add a specific policy that only allows access to the desired API routes.
Once the resources are deployed, you need to change the code in one of the Lambdas.
In lambdas/jobScheduler/lambda_function.py:
eventbridge.put_targets(
Rule=rule_name,
Targets=[
{
'Id': '1',
'Arn': 'arn:aws:lambda:ap-southeast-1:537124958292:function:speedbands-DataCollectionLambda-9brbU9wtHbSD',
'Input': json.dumps({
'body': {
'jobId': job_id
}
})
}
]
)Replace the string following 'Arn': with the ARN of your DataCollection lambda.
Then, in backend/lambdas/dataCollection/src/lambda_function.py and backend/lambdas/jobChecker/lambda_function.py:
S3_BUCKET = "results-537124958292-ap-southeast-1"Replace the string with the name of your S3 results bucket. This can be found through the AWS dashboard.
You'll then need to re-run sam build and sam deploy to update the Lambda code. You should only see "JobSchedulerLambda", "DataCollectionLambda" and their corresponding methods in the changeset.
- Navigate to the AWS Dashboard
- Navigate to API Gateway
- Click "APIs"
- Find the one you created
- Click "Stages"
- Click the one named "default", it should be the only one.
- Copy the "Invoke URL" that displays for that stage.
You'll need to connect AWS Amplify to your the API to allow authenticated requests. In speedbands/components/AuthProvider.tsx:
Change:
API: {
REST: {
"SpeedbandsAPI": {
endpoint: "YOUR ENDPOINT HERE",
region: "ap-southeast-1"
}
}
}so that the endpoint: contains the Invoke URL you obtained above.