@vyriy/stack 0.1.18 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,22 @@ AWS CDK stack helpers for Vyriy projects.
6
6
 
7
7
  This package keeps small, reusable CDK construction helpers close to the AWS primitives they wrap. The helpers are intentionally thin: they provide calm defaults for common Vyriy infrastructure while leaving the full CDK prop objects available to callers.
8
8
 
9
+ ## Install
10
+
11
+ With npm:
12
+
13
+ ```bash
14
+ npm install @vyriy/stack aws-cdk-lib
15
+ ```
16
+
17
+ With Yarn:
18
+
19
+ ```bash
20
+ yarn add @vyriy/stack aws-cdk-lib
21
+ ```
22
+
23
+ The `aws-cdk-lib` package is listed because CDK apps and bin entrypoints use CDK stack, app, prop, and resource types directly.
24
+
9
25
  ## API
10
26
 
11
27
  - `s3.createBucket(scope, id, props?)` creates a private S3 bucket with static-site-friendly defaults.
@@ -18,6 +34,7 @@ This package keeps small, reusable CDK construction helpers close to the AWS pri
18
34
  - `route53.createCloudFrontTarget(distribution)` creates a Route 53 alias target for CloudFront.
19
35
  - `acm.createCertificate(scope, id, props)` creates an ACM certificate.
20
36
  - `deployment.createBucketDeployment(scope, id, props)` deploys files to S3 with a `512` MB default memory limit.
37
+ - `deployment.createHtmlCacheControl()` creates cache-control headers for HTML files that should revalidate before reuse.
21
38
  - `deployment.createImmutableCacheControl(days?)` creates long-lived immutable cache-control headers.
22
39
  - `deployment.Source` and `deployment.CacheControl` are re-exported from `aws-cdk-lib/aws-s3-deployment`.
23
40
 
@@ -26,13 +43,12 @@ This package keeps small, reusable CDK construction helpers close to the AWS pri
26
43
  This example wires the package helpers into a static website stack:
27
44
 
28
45
  - find an existing hosted zone
29
- - create a private S3 bucket for `vyriy.dev`
30
- - create a redirect S3 bucket for `www.vyriy.dev`
46
+ - create a private S3 bucket for `site.com`
31
47
  - create a DNS-validated ACM certificate
32
- - create one CloudFront distribution for the main site
33
- - create one CloudFront distribution for the `www` redirect
34
- - create Route 53 alias records
35
- - deploy local site files into the main bucket and invalidate CloudFront
48
+ - create a CloudFront distribution for the site
49
+ - create a Route 53 alias record
50
+ - deploy immutable assets and revalidating HTML files into the bucket
51
+ - invalidate CloudFront after each deployment
36
52
 
37
53
  CloudFront requires ACM certificates for custom aliases to be in `us-east-1`, so deploy this stack in `us-east-1` or split the certificate into a dedicated us-east-1 stack.
38
54
 
@@ -46,7 +62,7 @@ import { path } from '@vyriy/path';
46
62
 
47
63
  stack(
48
64
  class StaticSiteStack extends Stack {
49
- constructor(scope: Construct, id: string, props?: StackProps) {
65
+ constructor(scope: Construct, id: string, props: StackProps & { env: { account: string; region: string } }) {
50
66
  super(scope, id, props);
51
67
 
52
68
  const domain = 'site.com';
@@ -55,7 +71,7 @@ stack(
55
71
  domainName: domain,
56
72
  });
57
73
 
58
- const bucket = s3.createBucket(this, 'Bucket', {
74
+ const siteBucket = s3.createBucket(this, 'Bucket', {
59
75
  bucketName: domain,
60
76
  });
61
77
 
@@ -65,9 +81,9 @@ stack(
65
81
  validation: acm.CertificateValidation.fromDns(hostedZone),
66
82
  });
67
83
 
68
- const distribution = cf.createDistribution(this, 'Distribution', {
84
+ const siteDistribution = cf.createDistribution(this, 'Distribution', {
69
85
  certificate,
70
- defaultBehavior: cf.createDefaultBehavior(bucket),
86
+ defaultBehavior: cf.createDefaultBehavior(siteBucket),
71
87
  defaultRootObject: 'index.html',
72
88
  domainNames: [domain],
73
89
  errorResponses: [
@@ -85,17 +101,43 @@ stack(
85
101
  });
86
102
 
87
103
  route53.createARecord(this, 'RootRecord', {
88
- target: route53.createCloudFrontTarget(distribution),
104
+ target: route53.createCloudFrontTarget(siteDistribution),
89
105
  zone: hostedZone,
90
106
  });
91
107
 
92
- deployment.createBucketDeployment(this, 'DeploySite', {
108
+ const assetDeployment = deployment.createBucketDeployment(this, 'DeploySiteAssets', {
93
109
  cacheControl: deployment.createImmutableCacheControl(),
94
- destinationBucket: bucket,
95
- distribution,
110
+ destinationBucket: siteBucket,
111
+ distribution: siteDistribution,
112
+ exclude: ['index.html', '404.html'],
96
113
  distributionPaths: ['/*'],
97
114
  sources: [deployment.Source.asset(path('dist'))],
98
115
  });
116
+
117
+ const htmlDeployment = deployment.createBucketDeployment(this, 'DeploySiteHtml', {
118
+ cacheControl: deployment.createHtmlCacheControl(),
119
+ destinationBucket: siteBucket,
120
+ distribution: siteDistribution,
121
+ distributionPaths: ['/*'],
122
+ exclude: ['*'],
123
+ include: ['index.html', '404.html'],
124
+ prune: false,
125
+ sources: [deployment.Source.asset(path('dist'))],
126
+ });
127
+
128
+ htmlDeployment.node.addDependency(assetDeployment);
129
+
130
+ new CfnOutput(this, 'Account', { value: props.env.account });
131
+ new CfnOutput(this, 'Region', { value: props.env.region });
132
+ new CfnOutput(this, 'Tags', { value: JSON.stringify(props.tags ?? {}) });
133
+
134
+ new CfnOutput(this, 'BucketName', { value: siteBucket.bucketName });
135
+
136
+ new CfnOutput(this, 'DistributionDomainName', { value: siteDistribution.domainName });
137
+ new CfnOutput(this, 'DistributionId', { value: siteDistribution.distributionId });
138
+ new CfnOutput(this, 'DistributionUrl', { value: `https://${siteDistribution.domainName}/` });
139
+
140
+ new CfnOutput(this, 'SiteUrl', { value: `https://${domain}/` });
99
141
  }
100
142
  },
101
143
  );
@@ -3,3 +3,4 @@ import { BucketDeployment, BucketDeploymentProps, CacheControl, Source } from 'a
3
3
  export { Source, CacheControl };
4
4
  export declare const createBucketDeployment: (scope: Construct, id: string, props: BucketDeploymentProps) => BucketDeployment;
5
5
  export declare const createImmutableCacheControl: (days?: number) => CacheControl[];
6
+ export declare const createHtmlCacheControl: () => CacheControl[];
@@ -10,3 +10,8 @@ export const createImmutableCacheControl = (days = 365) => [
10
10
  CacheControl.maxAge(Duration.days(days)),
11
11
  CacheControl.immutable(),
12
12
  ];
13
+ export const createHtmlCacheControl = () => [
14
+ CacheControl.setPublic(),
15
+ CacheControl.maxAge(Duration.seconds(0)),
16
+ CacheControl.mustRevalidate(),
17
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vyriy/stack",
3
- "version": "0.1.18",
3
+ "version": "0.1.21",
4
4
  "description": "AWS CDK stack helpers for Vyriy infrastructure",
5
5
  "type": "module",
6
6
  "main": "./index.js",