Skip to content

Cloud backend for hello.nrfcloud.com developed using AWS CDK in TypeScript

License

Notifications You must be signed in to change notification settings

hello-nrfcloud/backend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

hello.nrfcloud.com backend

GitHub Actions semantic-release Renovate @commitlint/config-conventional code style: prettier ESLint: TypeScript

Cloud backend for hello.nrfcloud.com developed using AWS CDK in TypeScript.

Installation in your AWS account

Setup

Provide your AWS credentials.

Install the dependencies

npm ci

The CoAP simulator is written in Golang, which needs to be present on the local system.

Run once

To setup MQTT bridge, you have to run the below command to generate a certificate used by MQTT broker to connect nRF Cloud under your account. So, you need to prepare nRF Cloud API key.

./cli.sh configure-nrfcloud-account <account> apiKey <API key>
./cli.sh initialize-nrfcloud-account <account>
./cli.sh create-health-check-device <account>

nRF Cloud Location Services Service Key

The single-cell geo-location features uses the nRF Cloud Ground Fix API which requires the service to be enabled in the account's plan. Manage the account at https://nrfcloud.com/#/manage-plan.

Memfault integration

The backend fetches device metrics from Memfault. For this you need to configure the settings for your Memfault project:

./cli.sh configure-memfault organizationAuthToken <organizationAuthToken> # e.g. oat_18By8mEdkEj666666666666kIt9HwsMZ
./cli.sh configure-memfault organizationSlug <organizationSlug> # e.g. nordic-semiconductor-asa123456
./cli.sh configure-memfault projectSlug <projectSlug> # e.g. hello-nrfcloud-com

Build the docker images

Some of the feature are run from docker containers, ensure they have been built and published before deploying the solutions.

export MQTT_BRIDGE_CONTAINER_TAG=$(./cli.sh build-container mqtt-bridge)

# You can add these outputs to your .env file
echo MQTT_BRIDGE_CONTAINER_TAG=$MQTT_BRIDGE_CONTAINER_TAG

Deploy

npx cdk bootstrap # if this is the first time you use CDK in this account
npx cdk deploy --all

What messages MQTT bridge forwards

According to nRF Cloud documentation, Setting up a message bridge, all messages under <stage>/<team id>/m/# are bridged. Since the messages are forwarded from nRF Cloud, therefore all messages are following the protocol described here.

Note Shadow data will NOT be forwarded to MQTT bridge since they are using topic as $aws/things/${deviceId}/shadow/update

Adding another nRF Cloud team

The backend supports the integration with multiple nRF Cloud accounts.

Follow the steps above to set up the MQTT bridge for another account, then trigger a deployment.

npx cdk deploy --all

List the configured accounts:

./cli.sh list-nrfcloud-accounts

Continuous Deployment using GitHub Actions

After deploying the stack manually once,

  • configure a GitHub Actions environment named production
  • create the secret AWS_ROLE with the value arn:aws:iam::<account ID>:role/<stack name>-cd and a variable (use the cdRoleArn stack output)
  • create the variable AWS_REGION with the value <region> (your region)
  • create the variable STACK_NAME with the value <stack name> (your stack name)

to enable continuous deployment.

gh secret set AWS_ROLE --env production --body `arn:aws:iam::<account ID>:role/<stack name>-cd`
gh variable set AWS_REGION --env production --body <region>
gh variable set STACK_NAME --env production --body <stack name>

Custom API domain

Optionally, a custom API domain can be configured.

For this, create a certificate for the domain name in the Certificate Manager of the production account in the region of the deployment.

Create a role in the account that manages the domain name, to allow the the production account to update the CNAME for the API domain with these permissions (make sure to replace <Hosted Zone ID>, <api domain name>):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "route53:ChangeResourceRecordSets",
      "Resource": "arn:aws:route53:::hostedzone/<Hosted Zone ID>",
      "Condition": {
        "ForAllValues:StringEquals": {
          "route53:ChangeResourceRecordSetsNormalizedRecordNames": [
            "<api domain name>"
          ],
          "route53:ChangeResourceRecordSetsRecordTypes": ["CNAME"],
          "route53:ChangeResourceRecordSetsActions": ["UPSERT"]
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": "route53:ListHostedZonesByName",
      "Resource": "*"
    }
  ]
}

Then, for continuous deployment:

  • create the variable API_DOMAIN_NAME with the name of the api domain, e.g. api.hello.nordicsemi.cloud 53 zone that hosts the api domain records, e.g. eu-north-1
  • create the secret API_DOMAIN_ROUTE_53_ROLE_ARN with the role ARN of the role that allows the production account to update the CNAME for the API domain.
gh variable set API_DOMAIN_NAME --env production --body api.sim-details.nordicsemi.cloud
gh variable set API_DOMAIN_ROUTE_53_ROLE_ARN --env production --body arn:aws:iam::<account ID>:role/<role name>

Websocket Protocol

Message received from MQTT bridge will be published to websocket connection that associates with the same device id.

Messages will be converted using @hello.nrfcloud.com/proto.