UNPKG

@pwrdrvr/microapps-cdk

Version:

MicroApps framework, by PwrDrvr LLC, delivered as an AWS CDK construct that provides the DynamoDB, Router service, Deploy service, API Gateway, and CloudFront distribution.

333 lines (332 loc) 12.2 kB
import { RemovalPolicy } from 'aws-cdk-lib'; import * as acm from 'aws-cdk-lib/aws-certificatemanager'; import * as cf from 'aws-cdk-lib/aws-cloudfront'; import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; import * as r53 from 'aws-cdk-lib/aws-route53'; import { Construct } from 'constructs'; import { IMicroAppsCF } from './MicroAppsCF'; import { IMicroAppsEdgeToOrigin } from './MicroAppsEdgeToOrigin'; import { IMicroAppsS3 } from './MicroAppsS3'; import { IMicroAppsSvcs } from './MicroAppsSvcs'; /** * A CDK Construct for creating a MicroApps runtime environment used * to host Next.js, React, or any other sort of web application with * multiple versions available for comparison, quick rollbacks, quick * releases, and a complete lack of user disturbance on deploys. * * @remarks * * {@link MicroApps} provides a turn-key construct that creates all * dependencies with limited exposure of underlying AWS Resource options. * This construct is the easiest to use when exploring MicroApps for the * first time. * * {@link MicroAppsAPIGwy}, {@link MicroAppsCF}, {@link MicroAppsS3}, * and {@link MicroAppsSvcs}, and their helper static methods, can be used * to create AWS Resources more directly, to provide your own AWS Resources * (e.g. an existing CloudFront Distribution), and to have more flexibility * than the {@link MicroApps} construct offers. * * @packageDocumentation */ /** * Properties to initialize an instance of `MicroApps`. */ export interface MicroAppsProps { /** * RemovalPolicy override for child resources * * Note: if set to DESTROY the S3 buckes will have `autoDeleteObjects` set to `true` * * @default - per resource default */ readonly removalPolicy?: RemovalPolicy; /** * Passed to NODE_ENV of Router and Deployer Lambda functions. * * @default dev */ readonly appEnv: string; /** * Optional asset name root * * @example microapps * @default - resource names auto assigned */ readonly assetNameRoot?: string; /** * Optional asset name suffix * * @example -dev-pr-12 * @default none */ readonly assetNameSuffix?: string; /** * Route53 zone in which to create optional `domainNameEdge` record */ readonly r53Zone?: r53.IHostedZone; /** * Certificate in US-East-1 for the CloudFront distribution. */ readonly certEdge?: acm.ICertificate; /** * Certificate in deployed region for the API Gateway. */ readonly certOrigin?: acm.ICertificate; /** * Use a strict S3 Bucket Policy that prevents applications * from reading/writing/modifying/deleting files in the S3 Bucket * outside of the path that is specific to their app/version. * * This setting should be used when applications are less than * fully trusted. * * @default false */ readonly s3StrictBucketPolicy?: boolean; /** * Applies when using s3StrictBucketPolicy = true * * IAM Role or IAM User names to exclude from the DENY rules on the S3 Bucket Policy. * * Roles that are Assumed must instead have their AROA added to `s3PolicyBypassAROAs`. * * Typically any admin roles / users that need to view or manage the S3 Bucket * would be added to this list. * * @example ['arn:aws:iam::1234567890123:role/AdminAccess', 'arn:aws:iam::1234567890123:user/MyAdminUser'] * * @see s3PolicyBypassAROAs */ readonly s3PolicyBypassPrincipalARNs?: string[]; /** * Applies when using s3StrictBucketPolicy = true * * AROAs of the IAM Role to exclude from the DENY rules on the S3 Bucket Policy. * This allows sessions that assume the IAM Role to be excluded from the * DENY rules on the S3 Bucket Policy. * * Typically any admin roles / users that need to view or manage the S3 Bucket * would be added to this list. * * Roles / users that are used directly, not assumed, can be added to `s3PolicyBypassRoleNames` instead. * * Note: This AROA must be specified to prevent this policy from locking * out non-root sessions that have assumed the admin role. * * The notPrincipals will only match the role name exactly and will not match * any session that has assumed the role since notPrincipals does not allow * wildcard matches and does not do wildcard matches implicitly either. * * The AROA must be used because there are only 3 Principal variables available: * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#principaltable * aws:username, aws:userid, aws:PrincipalTag * * For an assumed role, aws:username is blank, aws:userid is: * [unique id AKA AROA for Role]:[session name] * * Table of unique ID prefixes such as AROA: * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-prefixes * * The name of the role is simply not available for an assumed role and, if it was, * a complicated comparison would be requierd to prevent exclusion * of applying the Deny Rule to roles from other accounts. * * To get the AROA with the AWS CLI: * aws iam get-role --role-name ROLE-NAME * aws iam get-user --user-name USER-NAME * * @example [ 'AROA1234567890123' ] * * @see s3StrictBucketPolicy */ readonly s3PolicyBypassAROAs?: string[]; /** * Optional custom domain name for the CloudFront distribution. * * @example apps.pwrdrvr.com * @default auto-assigned */ readonly domainNameEdge?: string; /** * Optional custom domain name for the API Gateway HTTPv2 API. * * @example apps-origin.pwrdrvr.com * @default auto-assigned */ readonly domainNameOrigin?: string; /** * Path prefix on the root of the CloudFront distribution * * @example dev/ */ readonly rootPathPrefix?: string; /** * Create API Gateway for non-edge invocation * * @default false */ readonly createAPIGateway?: boolean; /** * Create an extra Behavior (Route) for /api/ that allows * API routes to have a period in them. * * When false API routes with a period in the path will get routed to S3. * * When true API routes that contain /api/ in the path will get routed to API Gateway * even if they have a period in the path. * * @default true */ readonly createAPIPathRoute?: boolean; /** * Create an extra Behavior (Route) for /_next/data/ * This route is used by Next.js to load data from the API Gateway * on `getServerSideProps` calls. The requests can end in `.json`, * which would cause them to be routed to S3 if this route is not created. * * When false API routes with a period in the path will get routed to S3. * * When true API routes that contain /_next/data/ in the path will get routed to API Gateway * even if they have a period in the path. * * @default true */ readonly createNextDataPathRoute?: boolean; /** * Adds an X-Forwarded-Host-Header when calling API Gateway * * Can only be trusted if `signingMode` is enabled, which restricts * access to API Gateway to only IAM signed requests. * * Note: if true, creates OriginRequest Lambda @ Edge function for API Gateway Origin * @default true */ readonly addXForwardedHostHeader?: boolean; /** * Replaces Host header (which will be the Edge domain name) with the Origin domain name * when enabled. This is necessary when API Gateway has not been configured * with a custom domain name that matches the exact domain name used by the CloudFront * Distribution AND when the OriginRequestPolicy.HeadersBehavior is set * to pass all headers to the origin. * * Note: if true, creates OriginRequest Lambda @ Edge function for API Gateway Origin * @default true */ readonly replaceHostHeader?: boolean; /** * Requires IAM auth on the API Gateway origin if not set to 'none'. * * 'sign' - Uses request headers for auth. * 'presign' - Uses query string for auth. * * If enabled, * * Note: if 'sign' or 'presign', creates OriginRequest Lambda @ Edge function for API Gateway Origin * @default 'sign' */ readonly signingMode?: 'sign' | 'presign' | 'none'; /** * Origin region that API Gateway or Lambda function will be deployed to, used * for the config.yml on the Edge function to sign requests for * the correct region * * @default undefined */ readonly originRegion?: string; /** * Optional Origin Shield Region * * This should be the region where the DynamoDB is located so the * EdgeToOrigin calls have the lowest latency (~1 ms). * * @default originRegion if specified, otherwise undefined */ readonly originShieldRegion?: string; /** * Existing table for apps/versions/rules * * @warning - It is *strongly* suggested that production stacks create * their own DynamoDB Table and pass it into this construct, for protection * against data loss due to logical ID changes, the ability to configure * Provisioned capacity with Auto Scaling, the ability to add additional indices, etc. * * Requirements: * - Hash Key: `PK` * - Sort Key: `SK` * * @default created by construct */ readonly table?: dynamodb.ITable | dynamodb.ITableV2; /** * Pre-set table name for apps/versions/rules * * This is required when using v2 routing */ readonly tableNameForEdgeToOrigin?: string; /** * Additional edge lambda functions */ readonly edgeLambdas?: cf.EdgeLambda[]; /** * Account IDs allowed for cross-account Function URL invocations * * @default [] */ readonly allowedFunctionUrlAccounts?: string[]; /** * List of allowed locale prefixes for pages * * @example: ['en', 'fr', 'es'] * @default none */ readonly allowedLocalePrefixes?: string[]; /** * Additional IAM Role ARNs that should be allowed to invoke apps in child accounts */ readonly edgeToOriginRoleARNs?: string[]; } /** * Represents a MicroApps */ export interface IMicroApps { /** {@inheritdoc IMicroAppsCF} */ readonly cf: IMicroAppsCF; /** {@inheritdoc IMicroAppsEdgeToOrigin} */ readonly edgeToOrigin?: IMicroAppsEdgeToOrigin; /** {@inheritdoc IMicroAppsS3} */ readonly s3: IMicroAppsS3; /** {@inheritdoc IMicroAppsSvcs} */ readonly svcs: IMicroAppsSvcs; } /** * Create a new MicroApps "turnkey" construct for simple * deployments and for initial evaulation of the MicroApps framework. * * Use this construct to create a PoC working entire stack. * * Do not use this construct when adding MicroApps to an existing * CloudFront, API Gateway, S3 Bucket, etc. or where access * to all features of the AWS Resources are needed (e.g. to * add additional Behaviors to the CloudFront distribution, set authorizors * on API Gateway, etc.). * * @warning This construct is not intended for production use. * In a production stack the DynamoDB Table, API Gateway, S3 Buckets, * etc. should be created in a "durable" stack where the IDs will not * change and where changes to the MicroApps construct will not * cause failures to deploy or data to be deleted. * * @see {@link https://github.com/pwrdrvr/microapps-core/blob/main/packages/cdk/lib/MicroApps.ts | example usage in a CDK Stack } */ export declare class MicroApps extends Construct implements IMicroApps { private _cf; get cf(): IMicroAppsCF; private _edgeToOrigin?; get edgeToOrigin(): IMicroAppsEdgeToOrigin | undefined; private _s3; get s3(): IMicroAppsS3; private _svcs; get svcs(): IMicroAppsSvcs; constructor(scope: Construct, id: string, props?: MicroAppsProps); }