Updating Applications Securely on the HERE Platform with Gitlab

By Sophia Parafina | 03 June 2022

Try HERE Maps

Create a free API key to build location-aware apps and services.

Get Started

Migrating to the Basic or Limited HERE platform plans requires replacing the API key issued from the developer.here.com with a key generated by HERE platform. We’ve covered how to create a new API on platform previously, and this article demonstrates how to securely deploy an application using Gitlab CI/CD.

Deploying API Keys Securely

It’s essential to protect your keys when deploying your application. Let’s look at a common mistake and how to prevent it.

A common mistake is embedding your keys or credentials in the code when building an application for convenience. The key is visible in the source when viewed in the browser.

For example:

var platform = new H.service.Platform({
apikey: “my.api.key”
});

A better way to manage credentials in your HERE application is to use a JavaScript framework that compiles the keys or credentials at build time. We’ll use Next.js, a production-ready React framework, as an example. Next.js loads environment variables, such as API keys, from `.env.local`, e.g.:

// .env.local
BASE_PATH=/my-map-app
API_KEY=ABCD1EFGH2
SHARE_URL=https:/my.website.com/my-map-app

An advantage of using a .env.local file is that it can be excluded from a Git repository with a .gitignore file which prevents leakage of credentials. Because you can set environment variables for development, `.env.development`, or production, `.env.production`, it is best practice to use a wild card to prevent adding these files to the repository.

// .gitignore
.env.*.local

Keys, credentials, and other environment variables are read at runtime. In this example, we’re using `next.config.js which is a Node.js module that reads the `.env.local` file with process.env which is a Node.js global variable.

// next.config.js
const withPlugins = require("next-compose-plugins")
const optimizedImages = require("next-optimized-images")

module.exports = withPlugins([
[optimizedImages, { optimizeImagesInDev: true }],
])

module.exports = {
basePath: process.env.BASE_PATH || "",
publicRuntimeConfig: {
   basePath: process.env.BASE_PATH === "/" ? "" : process.env.BASE_PATH,
   apiKey: process.env.API_KEY,
   shareUrl: process.env.SHARE_URL,
},
}

Next.js can make a production build as a deployable static web application. In the `package.json` file of the application, we can add an export script.

// package.json
"scripts": {
  …
  "build": "next build",
  "export": "npm run build && next export",
}

To build the application, run:

$ npm run export

Next.js compiles and packages the source code and writes it to a directory called /out. The application is ready for securely deploying on your cloud provider.

Deploying with Gitlab CI/CD

Updating and deploying applications manually can be tedious and error-prone. A common solution is to use a Continuous Integration/Continuous Delivery tool, such as Gitlab, to automate the process.

This example demonstrates how to deploy a static web application in an AWS S3 bucket capable of hosting static websites. The first step is to add the following group variables (assuming that applications are deployed in a group). Gitlab provides detailed instructions for adding variables.

Group variables to set in Gitlab:

  • AWS_ACCES_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_REGION
  • S3_BUCKET_NAME_PROD
  • S3_BUCKET_NAME_REVIEW
  • CDN_DISTRIBUTION_ID

    gitlab variables panel

The next step is to configure the .gitlab-ci.yml file, which defines the scripts you want to run. It sets the configuration files and templates to include any required dependencies and caches. The .gitlab-ci.yml file sets the sequence of commands to run, the location to deploy applications, and if scripts are triggered automatically by an action such as a push or if actions are triggered manually. Gitlab provides thorough documentation on this configuration file.

The example below had three stages: a build stage, a review stage, and a deploy stage. The build stage creates the app to be deployed. This example deploys an app built on next.js and uses yarn to build the app. The next stage is the review stage which creates an ephemeral deployment used to evaluate the app before deployment. You can use s3 bucket policies to control access during the review stage. The deploy stage deploys the application to a publicly available s3 bucket configured as a static website.

stages:
- build
- review
- deploy

variables:
# Common
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
AWS_REGION: $AWS_REGION
S3_BUCKET_NAME: $S3_BUCKET_NAME
CDN_DISTRIBUTION_ID: $CDN_DISTRIBUTION_ID

cache:
key: $CI_COMMIT_REF_SLUG
paths:
       - node_modules/

Build:
stage: build
image: node:11
script:
      - yarn install
      - yarn build
      - yarn export
artifacts:
      paths:
     - build/
      expire_in: 1 day

Review:
stage: deploy
when: manual
before_script:
      - apk add --no-cache curl jq python py-pip
      - pip install awscli
       - eval $(aws ecr get-login --no-include-email --region $AWS_REGION | sed 's|https://||')
script:
      - aws s3 cp build/ s3://$S3_BUCKET_NAME_REVIEW/ --recursive --include "*"
       - aws cloudfront create-invalidation --distribution-id $CDN_DISTRIBUTION_ID --paths "/*"

Deploy:
stage: deploy
when: manual
before_script:
      - apk add --no-cache curl jq python py-pip
      - pip install awscli
       - eval $(aws ecr get-login --no-include-email --region $AWS_REGION | sed 's|https://||')
script:
      - aws s3 cp build/ s3://$S3_BUCKET_NAME_PROD/ --recursive --include "*"
      - aws cloudfront create-invalidation --distribution-id $CDN_DISTRIBUTION_ID --paths "/*"

Summary

Migrating to HERE platform is an excellent time to upgrade your deployment process. Make sure you deploy your API keys securely and automate the process for building and deploying applications.