Website Component

Deploys a static website with a CDN in front of object storage. Suitable for single-page applications, static sites, and front-end assets. Multiple website components can be declared in the same configuration — for example, a public marketing site and a separate admin portal, each with its own domain.

Configuration Fields

Field
Type
Required
Default
Description
type
string

required

—
Must be "website"
name
string

required

—
Unique component name. Becomes part of the globally unique resource name.
domain
string

required

—
The full domain name for this website (e.g. www.example.com or app.prod.example.com). The base domain is derived automatically as the last two labels (e.g. example.com) and must already be registered and have a hosted zone configured in your cloud provider. The plugin provisions the DNS record and HTTPS certificate for the full domain.
indexDocument
string

optional

"index.html"
The default document served for directory requests.
errorDocument
string

optional

"index.html"
The document served for 404 errors. Set to your SPA entry point for client-side routing.
httpsOnly
boolean

optional

true
Redirect HTTP to HTTPS. Strongly recommended.
cacheMaxAgeSeconds
integer

optional

86400
CDN cache TTL in seconds. Set to 0 to disable caching.
uploads
array

optional

—
List of Maven artifact upload definitions. Each entry deploys static content (HTML, CSS, JS) to the origin bucket at deploy time. Uses the same format as the Storage component's uploads field. See Storage component for full Upload Object documentation.
references
array of strings

optional

—
Names of components this website references. Supported targets: api-gateway. The plugin infers the relationship type and configures CORS automatically. Prefer using the links array with full link objects instead.
accessGate
object

optional

—
Puts an HTTP Basic username/password prompt in front of the whole site at the CDN edge. Credentials come from a secret (never inline). See Access Gate below. (AWS)
edgeFunctions
array

optional

—
Associates a user-provided CloudFront Function with the distribution on the viewer-request event (e.g. an edge language router). See Edge Functions below. (AWS)

The website component always provisions its own CDN-backed storage bucket for static assets. You do not need a separate storage component for website files — it is created automatically.

Initial Content Upload

Use the uploads field in providerSettings to deploy initial static content (HTML, CSS, JavaScript) to the origin bucket as part of the website deployment. This is especially useful for deploying pre-built frontend applications from Maven artifacts.

The upload format is identical to the Storage component's uploads field — including support for ${version} interpolation, inline classifier and extension in the artifact coordinate, and unpack: true for extracting archives.

{

  "type": "website",

  "name": "admin-tool",

  "providerSettings": {

    "domain": "admin.example.com",

    "uploads": [

      {

        "artifact": "com.example:admin-ui:${version}:dist:zip",

        "destination": "",

        "unpack": true

      }

    ]

  },

  "links": []

}

In this example, the artifact admin-ui-1.0.0-dist.zip is extracted and its contents are uploaded to the root of the origin bucket, making them immediately available via CloudFront.

Uploads run during the serverless:deploy phase, after the CloudFront distribution and bucket policy are configured. If the origin bucket already has content, uploads overwrite existing objects at the same path.

The base domain (last two labels of domain) must already be registered and have a hosted zone configured in your cloud provider — Route 53 (AWS), Azure DNS, or Cloud DNS (GCP). The plugin derives the base domain automatically: www.example.com → base example.com, app.prod.example.com → base example.com. It then provisions the full DNS record and an HTTPS certificate for the exact domain you specify.

Path-Based Storage Routing

Use WEBSITE_TO_STORAGE links with a path property to route specific URL paths to separate storage buckets. This is useful for serving large assets, user uploads, or media files from a dedicated bucket while keeping the main website content in the origin bucket.

{

  "type": "website",

  "name": "frontend",

  "providerSettings": {

    "domain": "www.example.com"

  },

  "links": [

    {

      "sourceComponent": "frontend",

      "targetComponent": "asset-store",

      "linkType": "WEBSITE_TO_STORAGE",

      "path": "/assets"

    },

    {

      "sourceComponent": "frontend",

      "targetComponent": "media-bucket",

      "linkType": "WEBSITE_TO_STORAGE",

      "path": "/media"

    }

  ]

}

In this example:

  • Requests to /assets/* are served from the asset-store S3 bucket
  • Requests to /media/* are served from the media-bucket S3 bucket
  • All other requests are served from the website's own origin bucket

The path property is required on WEBSITE_TO_STORAGE links and must start with /. The target storage component must be defined in the configuration. The plugin automatically configures CloudFront cache behaviors and sets bucket policies on the target buckets for secure access.

Azure: each WEBSITE_TO_STORAGE path is derived into a Front Door route pointing at the linked Storage Account origin ({path}/* → the target account). Route derivation is applied during deployment; provisioning the Front Door profile itself requires the azure-resourcemanager-cdn module (pending) — until then the derived routes are logged and the Static Web App resource ID is returned.

Access Gate (edge HTTP Basic auth)

The optional accessGate setting puts a username/password prompt in front of the entire site at the CDN edge. When enabled, every viewer request must carry a valid Authorization: Basic header, or the CDN returns 401 Unauthorized with a WWW-Authenticate: Basic realm="…" challenge, so browsers show a login prompt. It is ideal for gating staging or pre-release environments without adding application-level auth.

On AWS this is implemented as a CloudFront Function (runtime cloudfront-js-2.0) associated with the distribution's default cache behavior on the viewer-request event. The function is named {derived-name}-site-gate.

Credentials are never stored in configuration. They live in an AWS Secrets Manager secret that you reference by name or ARN. At deploy time the plugin reads the secret, computes the base64 Basic tokens, and bakes those tokens (never the raw passwords) into the generated edge function. CloudFront Functions cannot make network calls at request time, so the accepted credential set is fixed at deploy — rotate the secret and redeploy the website to change credentials.

accessGate Fields

Field
Type
Required
Default
Description
enabled
boolean or string

optional

false
Whether the gate is active. Accepts a boolean or the string "true"/"false" so it can be driven per environment via ${variable} substitution. Absent means disabled.
credentialsSecret
string

when enabled

—
The Secrets Manager secret name or ARN holding the credentials. Required whenever enabled is true.
realm
string

optional

"Restricted"
The HTTP Basic realm shown in the browser prompt.

Secret Payload Formats

The referenced secret may hold multiple credentials in any of these forms:

  • A JSON array of objects: [ { "username": "alice", "password": "s3cret" } ]
  • A JSON object mapping username to password: { "alice": "s3cret", "bob": "hunter2" }
  • Newline-separated username:password lines (blank lines and # comments are ignored).

Example

{

  "type": "website",

  "name": "marketing-site",

  "providerSettings": {

    "domain": "www.example.com",

    "accessGate": {

      "enabled": "${siteGateEnabled}",

      "credentialsSecret": "example/site-gate-credentials",

      "realm": "Example Staging"

    }

  },

  "links": []

}

Set siteGateEnabled to true in your staging variables and false in production to gate only pre-release environments. Disabling the gate and redeploying removes the function association; running serverless:undeploy deletes the CloudFront Function.

The access gate coexists with a WAF (WAF_TO_WEBSITE) association — only the default cache behavior's edge-function association is changed, so the distribution's WAF Web ACL is preserved on update.

Deploy permissions: enabling an access gate requires secretsmanager:GetSecretValue plus the CloudFront function actions (CreateFunction, UpdateFunction, PublishFunction, DescribeFunction, DeleteFunction) on the deploy identity — see Credentials.

Edge Functions (viewer-request)

The optional edgeFunctions setting associates a user-provided CloudFront Function with the distribution's default cache behavior on the viewer-request event. The function runs on every viewer request at the edge and can inspect or rewrite the request — for example, rewriting a bare path such as / to a localized document like /en/home.html based on a cookie or the Accept-Language header.

The function source is a project-relative JavaScript file, resolved against src/main/serverless (the same directory as config.json). It is read at deploy time, published as a cloudfront-js-2.0 function named {derived-name}-edge-viewer-request, and associated with the distribution. Redeploying updates the function code in place; serverless:undeploy deletes it after the distribution is removed.

edgeFunctions Fields (per entry)

Field
Type
Required
Default
Description
event
string

required

—
The CloudFront event. Only "viewer-request" is currently supported.
runtime
string

optional

"cloudfront-function"
The runtime discriminator. Only "cloudfront-function" is currently supported.
source
string

required

—
Project-relative path to the function source JavaScript, resolved against src/main/serverless. Must stay within that directory — absolute paths and .. traversal are rejected by validation.
variables
object

optional

—
Deploy-time ${key} substitutions applied to the source (string values). Unknown placeholders are left untouched, so sources may also be fully self-contained.

Example

{

  "type": "website",

  "name": "marketing-site",

  "providerSettings": {

    "domain": "www.example.com",

    "edgeFunctions": [

      {

        "event": "viewer-request",

        "runtime": "cloudfront-function",

        "source": "edge/language-router.js",

        "variables": { "supportedLanguages": "['en','fr','de']" }

      }

    ]

  },

  "links": []

}

Here src/main/serverless/edge/language-router.js is read at deploy time, any ${supportedLanguages} placeholder in it is replaced with ['en','fr','de'], and the result is published and associated on viewer-request.

One viewer-request function per website. CloudFront allows only one function association per event type per cache behavior. A viewer-request edge function and an enabled access gate (which also uses viewer-request) are therefore mutually exclusive — serverless:validate fails if both are declared on the same website. If you need both behaviors, fold the access check into your own edge function source and use only edgeFunctions.

Deploy permissions: edge functions require the CloudFront function actions (CreateFunction, UpdateFunction, PublishFunction, DescribeFunction, DeleteFunction) on the deploy identity — all covered by cloudfront:*. No Secrets Manager access is needed for edge functions.

Cloud Resources Created

  • S3 Bucket — automatically created to store the website files. Named {derived-name}. Versioning disabled by default.
  • CloudFront Distribution — CDN in front of the S3 bucket. Origin access control (OAC) restricts direct S3 access. HTTPS enforced. Compression is always enabled. Uses the AWS managed CachingOptimized cache policy (ID: 658327ea-f89d-4fab-a63d-7e88639e58f6) for optimal performance. Custom error responses are configured for 403 and 404 errors using errorDocument (defaults to index.html) with HTTP 200 status — this enables SPA client-side routing.
  • S3 Bucket Policy — grants CloudFront OAC read access to the bucket.
  • ACM Certificate — provisioned in us-east-1 for the configured domain. DNS-validated against the base domain's Route 53 hosted zone.
  • Route 53 Record — ALIAS record for the domain pointing to the CloudFront distribution.
  • CloudFront Function (only when accessGate.enabled) — a cloudfront-js-2.0 function named {derived-name}-site-gate that enforces HTTP Basic auth on the viewer-request event. Credentials are read from Secrets Manager at deploy time and baked in as base64 tokens. Removed on undeploy.
  • CloudFront Function (only when an edgeFunctions viewer-request entry is declared) — a cloudfront-js-2.0 function named {derived-name}-edge-viewer-request, published from your source file and associated on the viewer-request event. Updated in place on redeploy; removed on undeploy.

Redeploy Behavior: When the CloudFront distribution already exists, the deployer updates it with the latest configuration (compress, cache policy, error responses, path-based storage origins) rather than skipping it.

Path Routing: Each WEBSITE_TO_STORAGE link with a path property adds an additional S3 origin and a cache behavior for that path pattern. The OAC is shared, and bucket policies are automatically set on target buckets.

Limitations: The base domain must have an existing Route 53 hosted zone. Certificate DNS validation may take a few minutes on first deploy.

JSON Example

{

  "type": "website",

  "name": "frontend",

  "providerSettings": {

    "domain": "www.example.com",

    "indexDocument": "index.html",

    "errorDocument": "index.html",

    "httpsOnly": true,

    "cacheMaxAgeSeconds": 3600,

    "uploads": [

      {

        "artifact": "com.example:frontend-dist:${version}:static:zip",

        "destination": "",

        "unpack": true

      }

    ]

  },

  "links": [

    {

      "sourceComponent": "frontend",

      "targetComponent": "main-api",

      "linkType": "WEBSITE_TO_API_GATEWAY"

    }

  ]

}

Links

Use the links array to declare which components this website connects to. The plugin infers the relationship type from the target component type and configures permissions automatically.

Can reference →

API Gateway

Calls a backend API. Configures CORS on the API Gateway to allow requests from the website's subdomain origin.

Can reference →

Storage

Serves content from a separate storage bucket at a specific URL path. Requires the path property (e.g. "/assets"). Creates an additional CDN origin and path-based routing rule.