Deploying Google Lighthouse CI (LHCI) using AWS-CDK & Fargate

Share on:

Deploying a highly available, persistent Google Lighthouse interface through AWS-CDK

Table of Contents

Prelude - Show me the code!

The code is currently maintained on GitHub.

Intro - What’s Lighthouse?

Google Lighthouse is an open-source, automated tool for improving the quality of web pages. It can run against any web page and will provide recommendations for improvements. Lighthouse is developed by Google, with contributions from Microsoft, Mozilla and others.

Lighthouse works by checking a webpage against a set of criteria for performance and accessibility in order to identify potential issues that could affect users. The report generated by Lighthouse can be used as a starting point to fix problems or improve the page’s performance on various devices.

Why accessibility matters

What’s Section 508?

First and foremost, it’s important to know exactly what the rule means that you’re following for ADA compliance.

In 1998, the amendment titled Section 508 was created to require any organization that receives federal funding to make their digital properties accessible to all individuals, including those with disabilities. Because this applies to Medicare and Medicaid, most healthcare entities are included and thus have to abide by the guidelines.

In 2017, after being mostly unchanged for nearly 20 years, the U.S. Access Board updated accessibility requirements and created an easier-to-understand approach for those attempting to make their digital and electronic presence more accessible. One such creation was the inclusion of WCAG (Web Content Accessibility Guidelines) to help make all websites accessible via a checklist that web developers could follow. However, just as Section 508 changed, so does WCAG. It’s important now for healthcare entities to understand that following the most updated version (2.1) is highly recommended.

Patient Interaction

Interacting with your end-user (in some cases, a patient or those providing care) is an always changing process. With the adoption of telehealth & online check-ins within the past few years has made a lot of organizations take a pause and reflect.

If a patient is unable to access your website, not only do they become frustrated, but they may eventually give up and go to a different practice for assistance. Your web presence is a very crucial gateway to your practice, and must be accessible to all individuals. If it’s not, your practice is, in many ways, saying that you’re only catering to a specific group of individuals. More than 25 million people in the US alone experience disabilities that could hinder them from using your website as is, and that’s not a number you want to lose by any means.

How do I ensure compliance?

There are a number of things that you can do to your website to get better in compliance, but the only way to accurately know that your site is meeting compliance standards is to programmatically benchmark performance via a tool (did someone say, Google Lighthouse?!)

With that said, the regulations and standards could change, which is why it’s important that this process stays agile. The more your developers & editors contribute to your web presence, the more you run the risk of losing that stamp of compliance.

Deployment

Requirements

  1. An AWS Account with ample permissions
  2. AWS-CDK (latest - 2.23.0 (build 50444aa) as of writing)
  3. nodejs & npm

Initial Setup

  1. Configure cdk.json with your Route 53 forward zone and desired CNAME record name
  2. cdk deploy
  3. lhci wizard will yield something similar to:

me:/mnt/c/coderepo/lhci-fargate$ lhci wizard

? Which wizard do you want to run? new-project

? What is the URL of your LHCI server? https://lhci.example.com

? What would you like to name the project? tf-fargate

? Where is the project’s code hosted? https://github.com/example/tf-fargate

? What branch is considered the repo’s trunk or main branch? main

  1. Create a .lighthouserc.js file:

     module.exports = {
         ci: {
         collect: {
             url: "https://www.example.com",
             maxAutodiscoverUrls: 3,
             numberOfRuns: 2,
             settings: {
                 chromeFlags: "--no-sandbox",
                 onlyCategories: ["performance", "best-practices", "accessibility", "seo"],
                 skipAudits: ['uses-http2', 'uses-long-cache-ttl', 'link-text']
             }
         },
         upload: {
             target: 'lhci',
             serverBaseUrl: 'https://lhci.example.com',
             token: 'example-000-example',
             ignoreDuplicateBuildFailure: true,
             allowOverwriteOfLatestBranchBuild: true
         },
         },
     };
    
    1. Add the buildToken to the .lighthouserc.js file to the token value

    2. Browse to the LHCI server (for example, https://lhci.example.com and click the gear in the upper-hand left corner)

    3. Add in the adminToken to the field in the settings for the LH project

    4. Run lhci autorun to run the lh-cli with the settings defined in the .lighthouserc.js file

       PS C:\coderepo\lhci-fargate> lhci autorun
       ✅  .lighthouseci/ directory writable
       ✅  Configuration file found
       ✅  Chrome installation found
       ⚠️   GitHub token not set
       ✅  Ancestor hash determinable
       ✅  LHCI server reachable
       ✅  LHCI server API-compatible
       ✅  LHCI server token valid
       ✅  LHCI server can accept a build for this commit hash
       Healthcheck passed!
      
       Running Lighthouse 2 time(s) on https://www.troydieter.com
       Run #1...done.
       Run #2...done.
       Done running Lighthouse!
      
       Saving CI project tf-fargate (780548b4-d479-4403-9500-e57f87b64d8d)
       Saving CI build (9e77cb40-546e-4c64-b7b1-0ad538255d9b)
       Saved LHR to https://lhci.troydieter.com (2d027171-faf1-40af-bbdb-a4cc8a04a4d5)
       Saved LHR to https://lhci.troydieter.com (eef82c8e-cf94-4b3d-a76e-b4e7044e2096)
       Done saving build results to Lighthouse CI
       View build diff at https://lhci.troydieter.com/app/projects/tf-fargate/compare/9e77cb40-546e-4c64-b7b1-0ad538255d9b
       No GitHub token set, skipping GitHub status check.
      
       Done running autorun.
      
    5. Observe the results on the lhci server: https://lhci.example.com results

Read the Docs!

📚 Read the programmatically created documentation, here! 📚

It was created using TypeDoc:

TypeDoc converts comments in TypeScript source code into rendered HTML documentation or a JSON model. It is extensible and supports a variety of configurations.

Diagram

diagram

Noted cleanup

  1. You may need to clean up EFS filesystems when creating and destroying this CDK app (they may persist)
  2. Check for any lingering EIP’s that may resided

Outcome

What did we build?

We’ve built a Lighthouse server (LHCI) that can be easily integrated into your AWS CodeBuild process (via a buildspec file) that accomplishes the following:

1. Operational Excellence

* Driven through AWS-CDK TypeScript, allowing for an iterative process

2. Security

* TLS used for incoming connections on the Application Load Balancer (listener)
* Redirect HTTP/`80` to HTTPS/`443`
* IAM Roles & Policies that allow for just enough access
* Data is encrypted at transit and at rest (when feasible)
* AWS ACM Certificate associated with the Application Load Balancer listener

3. Reliability

* 2 ECS `tasks` (minimum), with a max of `4` tasks
* 1 Application Load Balancer with an associated target that sends traffic sent to the ECS Fargate containers
* Scale-In is supported, and is based on 75% CPU Load
* `EFS` (Elastic File System) with multiple endpoints in 3 `availability zones`

4. Performance Efficiency

* 1 ECS (Fargate) cluster utilizes a common container image (@google/LHCI)

5. Cost Optimization

* Containers & tasks are only executing when required
* Standard EFS usage is used, but can be changed to One Zone if needed

6. Sustainability

* Reduce waste by only running instances of the Lighthouse server when necessary

These adhere to the AWS Well-Architected Framework Pillars as shown here.