App
The App
declaration specifies a Blazor WebAssembly app for deployment. Each declaration is compiled and uploaded as part of the deployment process.
The Blazor app is supported by two nested stacks. The first one creates an S3 bucket to host the deployed app files using the LambdaSharp.App.Bucket module. The second one creates a REST API to send messages and metrics to Amazon CloudWatch and events to Amazon EventBridge using the LambdaSharp.App.Api. Within the app, use the Lambda
Use the lash new app command to add the App
declaration with a pre-configured project to the module. The new project can be launched with dotnet run
from within the folder with the app .csproj file. However, in this mode, the Blazor WebAssembly does not connect to app API since it is launched locally.
Modules with an App
declaration have an additional AppDeveloperMode
CloudFormation parameter. By default, AppDeveloperMode
is set to Disabled
. In this mode, the app API key is based on the CloudFormation stack identifier of the REST API and the assembly version identifier of the app. The CloudFormation stack identifier changes with every new deployment, while the assembly version identifier changes with every build. This ensures that every app deployment has a unique API key to secure communication with the app API. In addition, the web console only shows errors emitted by Lambda
When AppDeveloperMode
is Enabled
, the app API key is only based on the CloudFormation stack identifier. In addition, the CORS origin attribute is always set to *
to allow connections from any origin to make it easier to run the app on localhost and still connect to the app API. Finally, all Lambda
Syntax
App: String
Description: String
Project: String
LogRetentionInDays: Number or Expression
Pragmas:
- PragmaDefinition
Api:
RootPath: String or Expression
CorsOrigin: String or Expression
BurstLimit: Number or Expression
RateLimit: Number or Expression
EventSource: String or Expression
Bucket:
CloudFrontOriginAccessIdentity: String or Expression
ContentEncoding: String or Expression
Client:
ApiUrl: String or Expression
AppSettings:
String: Expression
Sources:
- SourceDefinition
Properties
Api
-
The
Api
section specifies the API configuration for the app.Required: No
The
Api
section has the following attributes:RootPath
-
The
RootPath
attribute specifies the root path for app API. The root path must be a single path segment. When omitted, the default value is".app"
.Required: No
Type: String
CorsOrigin
-
The
CorsOrigin
attribute specifies the source URL that is allowed to invoke the app API. The value must be http:// or https:// followed by a valid domain name in lowercase letters, or*
to allow any domain. When omitted, the default value is the website URL for the S3 app bucket.Required: No
Type: String
BurstLimit
-
The
BurstLimit
attribute specifies the maximum number of requests per second to the app API over a short period of time. When omitted, the default value is 200.Required: No
Type: Number
RateLimit
-
The
RateLimit
attribute specifies the maximum number of requests per second to the app API over a long period of time. When omitted, the default value is 100.Required: No
Type: Number
EventSource
-
The
EventSource
attribute specifies a 'Source' property override for app events. When empty, the 'Source' property is set by the app request. When omitted, the default value is the full module name, followed by the logical ID of the app. For example,My.Module::MyApp
.Required: No
Type: String
AppSettings
-
The
AppSettings
attribute specifies configuration values stored in theappsettings.Production.json
file. This file is read during initialization of the app.Required: No
Type: Map of key-value pair Expressions
Bucket
-
The
Bucket
section specifies the S3 bucket configuration for the app.Required: No
The
Bucket
section has the following attributes:CloudFrontOriginAccessIdentity
-
The
CloudFrontOriginAccessIdentity
attribute configures the S3 bucket for secure access from a CloudFront distribution. When omitted or left empty, the S3 bucket is configured as a public website instead.Required: No
Type: String
ContentEncoding
-
The
ContentEncoding
attribute sets the content encoding to apply to all files copied from the app package. The value must be one of:NONE
,BROTLI
,GZIP
, orDEFAULT
. When omitted, the default value isDEFAULT
.Required: No
Type: String
The
ContentEncoding
attribute must have one of the following values:NONE
-
No content encoding is performed and no
Content-Encoding
header is applied. Using no encoding is fastest to perform, but produces significantly larger files. BROTLI
-
Content is encoded with Brotli compression using the optimal compression setting. Brotli compression takes longer to perform, but produces smaller files.
Note that Brotli encoding is only valid for https:// connections.
GZIP
-
Content is encoded with Gzip compression. Gzip compression is faster than Brotli, but produces slightly larger files.
DEFAULT
-
The
DEFAULT
value defaults toBROTLI
when an emptyCloudFrontOriginAccessIdentity
attribute is specified since CloudFront distributions are always served over https:// connections. Otherwise, it defaults toGZIP
, which is safe for connections over https:// and http://.
Client
-
The
Client
section specifies the app client configuration.Required: No
The
Client
section has the following attributes:ApiUrl
-
The
ApiUrl
attribute specifies the URL used by the app client to connect to the app API. When omitted, the default value is the URL of the created API Gateway instance for the app.Required: No
Type: String
Description
-
The
Description
attribute specifies the description of the app.Required: No
Type: String
LogRetentionInDays
-
The
LogRetentionInDays
attribute specifies the number of days CloudWatch log entries are kept in the log group. When omitted, the default value is set byModule::LogRetentionInDays
.Required: No
Type: Number
Sources
-
The
Sources
section specifies zero or more source definitions for events to publish to the LambdaSharp App EventBus.Required: No
Type: List of Source Definition
Pragmas
-
The
Pragmas
section specifies directives that change the default compiler behavior.Required: No
Type: List of Pragma Definition
Project
-
The
Project
attribute specifies the relative path of the app project file or its folder.Required: Conditional. By default, the .NET Core project file is expected to be located in a sub-folder of the module definition. The name of the sub-folder and project file are expected to match the app name. If that is not the case, then the
Project
attribute must be specified. Otherwise, it can be omitted.Type: String
Nested Resources
The App
declaration adds two nested resources:
${AppName}::Bucket
is a CloudFormation stack using the LambdaSharp.App.Bucket module.${AppName}::Api
is a nested CloudFormation stack using the LambdaSharp.App.Api module.${AppName}::EventBus
is an optional nested CloudFormation stack using the LambdaSharp.App.EventBus module. It is only created when the app has event sources.
The nested stacks have output values that can be used to initialize other resources in the stack.
Examples
Creating a Blazor app
- App: MyBlazorApp
Creating a Blazor app with configuration values
- App: MyBlazorApp
AppSettings:
Title: !Sub "Welcome from ${AWS::StackName}"
Creating a Blazor app with a custom app API root path
- App: MyBlazorApp
Api:
RootPath: app-api
Client:
ApiUrl: !Sub "https://${WebsiteCloudFront.DomainName}/${MyBlazorApp::Api.Outputs.RootPath}"
Creating a Blazor app with CloudFront integration
The following app declaration configures the app API to allow access from any domain. Access could be restricted further using a custom domain, but not for dynamically generated CloudFront domain since the CloudFront distribution depends on the app API.
This example refers to the following resource declarations:
CloudFrontIdentity
is a resource of typeAWS::CloudFront::CloudFrontOriginAccessIdentity
CloudFront
is a resource of typeAWS::CloudFront::Distribution
- App: MyBlazorApp
Api:
CorsOrigin: "*"
Bucket:
CloudFrontOriginAccessIdentity: !Ref CloudFrontIdentity
Client:
ApiUrl: !Sub "https://${CloudFront.DomainName}/${MyBlazorApp::Api.Outputs.RootPath}"
Add the following to the Origins
section in the CloudFront distribution to proxy the app API:
Origins:
- Id: AppApi
DomainName: !GetAtt MyBlazorApp::Api.Outputs.DomainName
OriginPath: !GetAtt MyBlazorApp::Api.Outputs.CloudFrontOriginPath
CustomOriginConfig:
HTTPSPort: 443
OriginProtocolPolicy: https-only
Finally, add the following to the CacheBehaviors
section in the CloudFront distribution to proxy to the app API:
CacheBehaviors:
- TargetOriginId: AppApi
PathPattern: !GetAtt MyBlazorApp::Api.Outputs.CloudFrontPathPattern
AllowedMethods: [ GET, HEAD, OPTIONS, PUT, PATCH, POST, DELETE ]
ForwardedValues:
QueryString: false
Headers:
- X-Api-Key
ViewerProtocolPolicy: https-only