-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.ts
98 lines (89 loc) · 2.2 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import {
emptyProgram,
getStack,
nextAction,
operations,
runDeployment,
sigint,
sigquit,
} from '@mjuz/core';
import { at, changes, combine, sinkBehavior } from '@funkia/hareactive';
import * as aws from '@pulumi/aws';
import { PulumiFn } from '@pulumi/pulumi/automation';
import { isDeepStrictEqual } from 'util';
type State = { counter: number };
const programState = sinkBehavior<State>({ counter: 0 });
// Counter changes every 20 seconds, even though it is updated every second
setInterval(
() =>
programState.push({
counter: at(programState).counter + (Date.now() % 20000 < 1000 ? 1 : 0),
}),
1000
);
const program =
(state: State): PulumiFn =>
async () => {
// Create a bucket and expose a website index document
const bucket = new aws.s3.Bucket('website', {
website: {
indexDocument: 'index.html',
},
});
const content = `<html>
<head>
<title>Hello World! 👋🌍</title>
<meta charset="UTF-8">
</head>
<body>
<p>Hello World! 👋🌍</p>
<p>Counter: ${state.counter}</p>
</body>
</html>`;
// write our index.html into the site bucket
new aws.s3.BucketObject('index', {
bucket: bucket,
content: content,
contentType: 'text/html; charset=utf-8',
key: 'index.html',
});
// Configure bucket policy to allow public access
function publicReadPolicyForBucket(bucketArn: string): aws.iam.PolicyDocument {
return {
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Principal: '*',
Action: ['s3:GetObject'],
Resource: [`${bucketArn}/*`],
},
],
};
}
// Register bucket policy
new aws.s3.BucketPolicy('bucket-contents-policy', {
bucket: bucket.bucket,
policy: bucket.arn.apply(publicReadPolicyForBucket),
});
// Export the Internet address for the service.
return {
url: bucket.websiteEndpoint,
};
};
const initStack = getStack(
{
program: emptyProgram,
projectName: 'CentralizedWebPage',
stackName: 'CentralizedWebPage',
},
undefined,
{ 'aws:region': { value: 'us-east-1' } }
);
runDeployment(initStack, operations(programState.map(program)), (offerUpdates) =>
nextAction(
combine(offerUpdates, changes(programState, isDeepStrictEqual).mapTo(undefined)),
sigquit(),
sigint()
)
);