@ossy/deployment-tools 0.0.67 → 0.0.68
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 +45 -1
- package/package.json +1 -1
- package/src/caddy/caddy-config.js +4 -4
- package/src/caddy/caddy.playground.js +1 -1
- package/src/config/platform-config.js +28 -13
- package/src/deploy/platform-deployment.js +20 -28
- package/src/infrastructure/cli.js +14 -14
- package/src/infrastructure/container-server/container-server.js +31 -33
- package/src/infrastructure/deployment-target-stack.js +47 -0
- package/src/infrastructure/{establish-trust-stack.js → trust-ci-stack.js} +2 -2
- package/src/template/platform-template.js +1 -6
- package/src/infrastructure/platform-stack.js +0 -58
package/README.md
CHANGED
|
@@ -37,11 +37,55 @@ npx --yes @ossy/deployment-tools deploy \
|
|
|
37
37
|
--ossyfile packages/${{ github.event.inputs.packageName }}/ossy.json \
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
##
|
|
40
|
+
## Concepts
|
|
41
|
+
|
|
42
|
+
**Workspace**
|
|
43
|
+
|
|
44
|
+
A workspace is an umbrella for our services.
|
|
45
|
+
It needs to be associated with at least one billable account.
|
|
46
|
+
The workspace holds information like what tools and services are in use and should
|
|
47
|
+
be billed, and what users have access to these tools and services.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
participants: WorkspaceParticipant[];
|
|
53
|
+
services: ServiceDefinition[];
|
|
54
|
+
billingInformation
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Overview of our infrastructure
|
|
41
59
|
|
|
42
60
|
We use AWS to host our infrastructure and all of it is defined in JavaScript with the help of
|
|
43
61
|
(AWS CDK)[https://aws.amazon.com/cdk/].
|
|
44
62
|
|
|
63
|
+
**Static content**
|
|
64
|
+
|
|
65
|
+
We use a s3 bucket for static content.
|
|
66
|
+
This bucket is used to host websites, images, videos and other static content.
|
|
67
|
+
On root level you'll find directories that represent one workspace each.
|
|
68
|
+
|
|
69
|
+
/<workspacId>/<service>/
|
|
70
|
+
/<workspacId>/websites/website-id
|
|
71
|
+
|
|
72
|
+
The bucket have directories for each workspace that is the workspaceID.
|
|
73
|
+
|
|
74
|
+
The bucket have directories for each workspace that contains a media directory and website directories
|
|
75
|
+
|
|
76
|
+
- a place to host media files like images, videos, pdf documents etc.
|
|
77
|
+
- a platform to host different docker images to
|
|
78
|
+
- a mongodb database that can ensure data persistance without much effort from our our side
|
|
79
|
+
- an email service
|
|
80
|
+
- an easy way to host multiple single page applications
|
|
81
|
+
|
|
82
|
+
Stacks
|
|
83
|
+
|
|
84
|
+
- email service stack per env
|
|
85
|
+
- media bucket stack per env
|
|
86
|
+
- stack for dns records with the account that holds domain names
|
|
87
|
+
-
|
|
88
|
+
|
|
45
89
|
### Adding a new AWS account
|
|
46
90
|
We have a different account for each service and environment.
|
|
47
91
|
To add a new account follow the steps below.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/deployment-tools",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.68",
|
|
4
4
|
"description": "Collection of scripts and tools to aid deployment of containers and static files to Amazon Web Services through GitHub Actions",
|
|
5
5
|
"source": "./src/index.js",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -23,7 +23,7 @@ class CaddyConfigService {
|
|
|
23
23
|
|
|
24
24
|
const url = [
|
|
25
25
|
deploymentRequest.subdomain,
|
|
26
|
-
platformConfig.
|
|
26
|
+
platformConfig.environmentType !== 'prod' ? platformConfig.environmentType : undefined,
|
|
27
27
|
platformConfig.domain
|
|
28
28
|
]
|
|
29
29
|
.filter(x => !!x)
|
|
@@ -44,18 +44,18 @@ class CaddyConfigService {
|
|
|
44
44
|
listen: [':80', ':443'],
|
|
45
45
|
routes: [
|
|
46
46
|
{
|
|
47
|
-
match: [Matchers.host(`${platformConfig.ciSubDomain}.${platformConfig.
|
|
47
|
+
match: [Matchers.host(`${platformConfig.ciSubDomain}.${platformConfig.environmentType}.${platformConfig.domain}`)],
|
|
48
48
|
handle: [Handlers.subroute([{ handle: [Handlers.reverseProxy(platformConfig.ciInternalServerPort)]}])]
|
|
49
49
|
}
|
|
50
50
|
]
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
-
tls: platformConfig.
|
|
54
|
+
tls: platformConfig.environmentType === 'local-dev' ? undefined : {
|
|
55
55
|
automation: {
|
|
56
56
|
policies: [
|
|
57
57
|
{
|
|
58
|
-
subjects:[`*.${platformConfig.
|
|
58
|
+
subjects:[`*.${platformConfig.environmentType}.${platformConfig.domain}`],
|
|
59
59
|
issuers:[
|
|
60
60
|
{
|
|
61
61
|
challenges:{
|
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform config definition
|
|
3
|
+
* @typedef {Object} PlatformConfig
|
|
4
|
+
* @property {string} platformName - Name of platform
|
|
5
|
+
* @property {string} domain - example.com
|
|
6
|
+
* @property {string} environmentType - local, test, qa, prod
|
|
7
|
+
*
|
|
8
|
+
* @property {string} awsAccountId - Aws account id
|
|
9
|
+
* @property {string=} awsRegion - ?
|
|
10
|
+
* @property {string=} awsKeyPairName - ?
|
|
11
|
+
* @property {string} awsRoleToAssume - ?
|
|
12
|
+
* @property {string=} awsDeploymentSqsArn - ?
|
|
13
|
+
*
|
|
14
|
+
* @property {string=} ciSubDomain - ?
|
|
15
|
+
* @property {string|mumber=} ciInternalServerPort - ? | number;
|
|
16
|
+
* @property {string=} ciServerName - ?
|
|
17
|
+
* @property {string=} ciDockerNetworkName - ?
|
|
18
|
+
* @property {string} ciGithubActionsRepo - organisation/repoName
|
|
19
|
+
*/
|
|
20
|
+
|
|
1
21
|
const SupportedRegions = {
|
|
2
22
|
North: 'eu-north-1'
|
|
3
23
|
}
|
|
@@ -11,16 +31,10 @@ const SupportedEnvironments = {
|
|
|
11
31
|
}
|
|
12
32
|
|
|
13
33
|
const SupportedDeploymentTypes = {
|
|
14
|
-
Container: 'CONTAINER'
|
|
15
|
-
|
|
34
|
+
Container: 'CONTAINER',
|
|
35
|
+
Static: 'STATIC'
|
|
16
36
|
}
|
|
17
37
|
|
|
18
|
-
// export interface PlatformConfig extends Required<Omit<PlatformTemplate, 'awsRoleToAssume' | 'awsKeyPairName'>> {
|
|
19
|
-
// activeEnvironment: SupportedEnvironments;
|
|
20
|
-
// awsRoleToAssume?: string;
|
|
21
|
-
// awsKeyPairName?: string;
|
|
22
|
-
// }
|
|
23
|
-
|
|
24
38
|
/**
|
|
25
39
|
* @class
|
|
26
40
|
*/
|
|
@@ -31,17 +45,18 @@ class PlatformConfigService {
|
|
|
31
45
|
const withDefaults = {
|
|
32
46
|
platformName: SupportedEnvironments.LOCAL,
|
|
33
47
|
domain: 'localhost',
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
environmentType: SupportedEnvironments.LOCAL,
|
|
49
|
+
awsRegion: SupportedRegions.North,
|
|
50
|
+
...template,
|
|
51
|
+
// values below should not be overriden by the template properties
|
|
36
52
|
ciSubDomain: 'ci',
|
|
37
53
|
ciInternalServerPort: 3000,
|
|
38
54
|
ciServerName: 'ci-client',
|
|
39
55
|
ciDockerNetworkName: 'deployment-tools',
|
|
40
|
-
awsRegion: SupportedRegions.North,
|
|
41
|
-
...template
|
|
42
56
|
}
|
|
43
57
|
|
|
44
|
-
const awsDeploymentSqsArn =
|
|
58
|
+
const awsDeploymentSqsArn =
|
|
59
|
+
`https://sqs.${withDefaults.awsRegion}.amazonaws.com/${withDefaults.awsAccountId}/${withDefaults.platformName}-${withDefaults.environmentType}`
|
|
45
60
|
|
|
46
61
|
const awsRoleToAssume = process.env.CI
|
|
47
62
|
? `github-ci-role-${withDefaults.platformName}`
|
|
@@ -45,38 +45,38 @@ class PlatformDeploymentService {
|
|
|
45
45
|
pathToOssyFile
|
|
46
46
|
}) {
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
.
|
|
50
|
-
.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return Promise.all([platformConfigRequest, deploymentTemplatesRequest])
|
|
55
|
-
.then(([platformConfigs, deploymentTemplates]) => {
|
|
48
|
+
return Promise.all([
|
|
49
|
+
PlatformDeploymentService.getDeploymentTemplates(pathToOssyFile),
|
|
50
|
+
PlatformTemplateService.readFromFile(pathToPlatformTemplates)
|
|
51
|
+
.then(templates => templates.map(PlatformConfigService.from))
|
|
52
|
+
])
|
|
53
|
+
.then(([deploymentTemplates, platformConfigs]) => {
|
|
56
54
|
deploymentTemplates.map(deploymentTemplate => {
|
|
57
55
|
|
|
58
|
-
const platformConfig = platformConfigs.find(config =>
|
|
56
|
+
const platformConfig = platformConfigs.find(config =>
|
|
57
|
+
config.platformName === deploymentTemplate.targetDeploymentPlatform
|
|
58
|
+
&& config.environmentType == targetEnvironment
|
|
59
|
+
)
|
|
59
60
|
|
|
60
61
|
if (!platformConfig) {
|
|
61
|
-
logError({ message: `[PlatformDeploymentService] Could not find a deployment platform with the name ${deploymentTemplate.targetDeploymentPlatform}` })
|
|
62
|
+
logError({ message: `[PlatformDeploymentService] Could not find a deployment platform with the name ${deploymentTemplate.targetDeploymentPlatform} and environment type ${targetEnvironment}` })
|
|
62
63
|
return Promise.reject()
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
|
66
67
|
|
|
67
|
-
if (deploymentTemplate.type
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
if (deploymentTemplate.type === SupportedDeploymentTypes.Container) {
|
|
69
|
+
const deploymentRequest = {
|
|
70
|
+
...deploymentTemplate,
|
|
71
|
+
username: username,
|
|
72
|
+
authentication: authentication
|
|
73
|
+
}
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
...deploymentTemplate,
|
|
74
|
-
env: PlatformDeploymentService.getEnvironmentVariables(targetEnvironment, deploymentTemplate),
|
|
75
|
-
username: username,
|
|
76
|
-
authentication: authentication
|
|
75
|
+
return DeploymentQueueService.sendDeploymentRequest(platformConfig, deploymentRequest)
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
|
|
78
|
+
logError({ message: `[PlatformDeploymentService] Unsupported deployment type of ${deploymentTemplate.type}` })
|
|
79
|
+
return Promise.reject()
|
|
80
80
|
|
|
81
81
|
})
|
|
82
82
|
})
|
|
@@ -89,14 +89,6 @@ class PlatformDeploymentService {
|
|
|
89
89
|
return Promise.resolve(ossyfile.deployments || [])
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
static getEnvironmentVariables(targetEnvironment, deploymentRequest) {
|
|
93
|
-
const envs = deploymentRequest.env || {}
|
|
94
|
-
return {
|
|
95
|
-
...(envs.shared || {}),
|
|
96
|
-
...(envs[targetEnvironment] || {})
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
92
|
}
|
|
101
93
|
|
|
102
94
|
module.exports = {
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/* eslint-disable no-new */
|
|
3
3
|
const { App } = require('aws-cdk-lib')
|
|
4
|
-
|
|
5
|
-
const {
|
|
6
|
-
const { EstablishTrustStack } = require('./establish-trust-stack')
|
|
7
|
-
|
|
4
|
+
const { TrustCiStack } = require('./trust-ci-stack')
|
|
5
|
+
const { DeploymentTargetStack } = require('./deployment-target-stack')
|
|
8
6
|
const { PlatformTemplateService } = require('../template')
|
|
9
7
|
const { PlatformConfigService } = require('../config')
|
|
10
8
|
|
|
@@ -12,19 +10,21 @@ PlatformTemplateService
|
|
|
12
10
|
.readFromFile(process.env.PLATFORMS)
|
|
13
11
|
.then(templates => templates.map(PlatformConfigService.from))
|
|
14
12
|
.then(configs => {
|
|
15
|
-
|
|
16
13
|
const app = new App()
|
|
17
14
|
|
|
18
15
|
configs.forEach(config => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
const stackBaseName = `${config.platformName}-${config.environmentType}`
|
|
17
|
+
|
|
18
|
+
const stackProps = {
|
|
19
|
+
config,
|
|
20
|
+
env: {
|
|
21
|
+
account: config.awsAccountId,
|
|
22
|
+
region: config.awsRegion
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
new TrustCiStack(app, `${stackBaseName}-trust-ci`, stackProps)
|
|
27
|
+
new DeploymentTargetStack(app, `${stackBaseName}-deployment-target`, stackProps)
|
|
28
28
|
|
|
29
29
|
})
|
|
30
30
|
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { CfnOutput } = require('aws-cdk-lib')
|
|
1
|
+
const { CfnOutput, Duration, RemovalPolicy } = require('aws-cdk-lib')
|
|
2
2
|
const { Construct } = require('constructs')
|
|
3
3
|
const {
|
|
4
4
|
Instance,
|
|
@@ -12,8 +12,11 @@ const {
|
|
|
12
12
|
Port,
|
|
13
13
|
UserData
|
|
14
14
|
} = require('aws-cdk-lib/aws-ec2')
|
|
15
|
-
const {
|
|
15
|
+
const { ARecord, RecordTarget } = require('aws-cdk-lib/aws-route53')
|
|
16
16
|
const { Role, ServicePrincipal, Policy, PolicyStatement, Effect } = require('aws-cdk-lib/aws-iam')
|
|
17
|
+
const { Queue } = require('aws-cdk-lib/aws-sqs')
|
|
18
|
+
const { Source, BucketDeployment } = require('aws-cdk-lib/aws-s3-deployment')
|
|
19
|
+
|
|
17
20
|
const {
|
|
18
21
|
getInstallNodeJs,
|
|
19
22
|
getInstallNpm,
|
|
@@ -22,15 +25,18 @@ const {
|
|
|
22
25
|
const { CaddyService } = require('./caddy.service')
|
|
23
26
|
const { DeploymentToolsService } = require('./deployment-tools.service')
|
|
24
27
|
const { AwsProfile } = require('./aws-profile')
|
|
28
|
+
|
|
25
29
|
const { SupportedRegions } = require('../../config')
|
|
26
30
|
|
|
27
31
|
/**
|
|
28
|
-
*
|
|
32
|
+
* ContainerServerProps
|
|
29
33
|
* @namespace ContainerServer
|
|
30
34
|
* @typedef {Object} ContainerServerProps
|
|
31
|
-
* @property {PlatformConfig}
|
|
32
|
-
* @property {
|
|
35
|
+
* @property {PlatformConfig} config - platform config
|
|
36
|
+
* @property {Zone} hostedZone - aws zone
|
|
37
|
+
* @property {Bucket} bucket - s3 bucket
|
|
33
38
|
*/
|
|
39
|
+
|
|
34
40
|
const InstanceImages = {
|
|
35
41
|
UBUNTU: 'ami-092cce4a19b438926'
|
|
36
42
|
}
|
|
@@ -41,8 +47,6 @@ const InstanceImages = {
|
|
|
41
47
|
class ContainerServer extends Construct {
|
|
42
48
|
|
|
43
49
|
/**
|
|
44
|
-
* EC2 Instance that docker containers are served on
|
|
45
|
-
*
|
|
46
50
|
* @param {object} scope - scope
|
|
47
51
|
* @param {string} id - id
|
|
48
52
|
* @param {ContainerServerProps} props - ContainerServerProps
|
|
@@ -50,18 +54,8 @@ class ContainerServer extends Construct {
|
|
|
50
54
|
constructor(scope, id, props) {
|
|
51
55
|
super(scope, id)
|
|
52
56
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
const vpc = Vpc.fromLookup(this, 'VPC', {
|
|
58
|
-
isDefault: true
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
const securityGroup = new SecurityGroup(this, 'SecurityGroup', {
|
|
62
|
-
vpc,
|
|
63
|
-
allowAllOutbound: true
|
|
64
|
-
})
|
|
57
|
+
const vpc = Vpc.fromLookup(this, 'VPC', { isDefault: true })
|
|
58
|
+
const securityGroup = new SecurityGroup(this, 'SecurityGroup', { vpc, allowAllOutbound: true })
|
|
65
59
|
|
|
66
60
|
securityGroup.addIngressRule(
|
|
67
61
|
Peer.anyIpv4(),
|
|
@@ -81,6 +75,16 @@ class ContainerServer extends Construct {
|
|
|
81
75
|
'allow HTTPS traffic from anywhere'
|
|
82
76
|
)
|
|
83
77
|
|
|
78
|
+
const deploymentQueue = new Queue(this, 'DeploymentQueue', {
|
|
79
|
+
queueName: `${props.config.platformName}-${props.config.environmentType}`,
|
|
80
|
+
receiveMessageWaitTime: Duration.seconds(20)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
const platformConfigDeployment = new BucketDeployment(this, 'PlatformConfigDeployment', {
|
|
84
|
+
sources: [Source.jsonData('platform-config.json', props.config)],
|
|
85
|
+
destinationBucket: props.bucket
|
|
86
|
+
})
|
|
87
|
+
|
|
84
88
|
const role = new Role(this, 'role', {
|
|
85
89
|
assumedBy: new ServicePrincipal('ec2.amazonaws.com')
|
|
86
90
|
})
|
|
@@ -95,7 +99,7 @@ class ContainerServer extends Construct {
|
|
|
95
99
|
'route53:ChangeResourceRecordSets'
|
|
96
100
|
],
|
|
97
101
|
resources: [
|
|
98
|
-
`arn:aws:route53:::hostedzone/${hostedZone.hostedZoneId}`,
|
|
102
|
+
`arn:aws:route53:::hostedzone/${props.hostedZone.hostedZoneId}`,
|
|
99
103
|
'arn:aws:route53:::change/*'
|
|
100
104
|
]
|
|
101
105
|
}),
|
|
@@ -127,7 +131,7 @@ class ContainerServer extends Construct {
|
|
|
127
131
|
)
|
|
128
132
|
|
|
129
133
|
userData.addS3DownloadCommand({
|
|
130
|
-
bucket: props.
|
|
134
|
+
bucket: props.bucket,
|
|
131
135
|
bucketKey: 'platform-config.json',
|
|
132
136
|
localFile: '/home/ubuntu/platform-config.json'
|
|
133
137
|
})
|
|
@@ -152,25 +156,19 @@ class ContainerServer extends Construct {
|
|
|
152
156
|
machineImage: new GenericLinuxImage({
|
|
153
157
|
[SupportedRegions.North]: InstanceImages.UBUNTU
|
|
154
158
|
}),
|
|
155
|
-
keyName: props.
|
|
159
|
+
keyName: props.config.awsKeyPairName
|
|
156
160
|
})
|
|
157
161
|
|
|
158
|
-
props.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
// const hostedZone = !!props.createNewHostedZone
|
|
162
|
-
// ? new PublicHostedZone(this, 'HostedZone', { zoneName: props.domain })
|
|
163
|
-
// : HostedZone.fromLookup(this, 'HostedZone', { domainName: props.domain });
|
|
162
|
+
props.bucket.grantRead(ec2Instance, '*')
|
|
163
|
+
deploymentQueue.grant(ec2Instance, '*')
|
|
164
164
|
|
|
165
|
-
// eslint-disable-next-line no-new
|
|
166
165
|
new ARecord(this, 'WildcardRecord', {
|
|
167
|
-
zone: hostedZone,
|
|
168
|
-
recordName: `*.${props.
|
|
166
|
+
zone: props.hostedZone,
|
|
167
|
+
recordName: `*.${props.config.environmentType}.${props.config.domain}`,
|
|
169
168
|
target: RecordTarget.fromIpAddresses(ec2Instance.instancePublicIp)
|
|
170
169
|
})
|
|
171
170
|
|
|
172
|
-
|
|
173
|
-
new CfnOutput(this, 'Intance Ip', {
|
|
171
|
+
new CfnOutput(this, 'Instance Ip', {
|
|
174
172
|
value: ec2Instance.instancePublicIp,
|
|
175
173
|
description: 'Public ip of the ec2 instance',
|
|
176
174
|
exportName: 'instanceIp'
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* eslint-disable no-new */
|
|
2
|
+
const { nanoid } = require('nanoid')
|
|
3
|
+
const { Stack, Duration, RemovalPolicy } = require('aws-cdk-lib')
|
|
4
|
+
const { HostedZone, ARecord, RecordTarget } = require('aws-cdk-lib/aws-route53')
|
|
5
|
+
const { Bucket, BucketEncryption, BlockPublicAccess } = require('aws-cdk-lib/aws-s3')
|
|
6
|
+
const { ContainerServer } = require('./container-server')
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @class
|
|
10
|
+
*/
|
|
11
|
+
class DeploymentTargetStack extends Stack {
|
|
12
|
+
constructor(scope, id, props) {
|
|
13
|
+
super(scope, id, props)
|
|
14
|
+
|
|
15
|
+
if (!props?.config) {
|
|
16
|
+
throw ('[DeploymentTargetStack] No template provided')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const domain = `${props.config.environmentType}.${props.config.domain}`
|
|
20
|
+
const bucketId = nanoid().toLowerCase().replaceAll('_', '').replaceAll('-', '')
|
|
21
|
+
const bucketName = `${props.config.platformName}-${props.config.environmentType}-${bucketId}`
|
|
22
|
+
|
|
23
|
+
const hostedZone = new HostedZone(this, 'HostedZone', { zoneName: domain })
|
|
24
|
+
|
|
25
|
+
// TODO: this should probably not be destroyed....
|
|
26
|
+
const staticDeploymentTarget = new Bucket(this, 'StaticDeploymentTarget', {
|
|
27
|
+
bucketName: bucketName,
|
|
28
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
29
|
+
encryption: BucketEncryption.S3_MANAGED,
|
|
30
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
31
|
+
autoDeleteObjects: true
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
// Todo rename to container deployment target
|
|
35
|
+
// TODO: add persistant storage
|
|
36
|
+
new ContainerServer(this, 'ContainerDeploymentTarget', {
|
|
37
|
+
config: props.config,
|
|
38
|
+
hostedZone: hostedZone,
|
|
39
|
+
bucket: staticDeploymentTarget
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = {
|
|
46
|
+
DeploymentTargetStack
|
|
47
|
+
}
|
|
@@ -11,7 +11,7 @@ const {
|
|
|
11
11
|
/**
|
|
12
12
|
* @class
|
|
13
13
|
*/
|
|
14
|
-
class
|
|
14
|
+
class TrustCiStack extends Stack {
|
|
15
15
|
/**
|
|
16
16
|
* Establishes trust between GithHub and Amazon Web Services.
|
|
17
17
|
* This is needed so that we can interact with Amazon Web Services through
|
|
@@ -64,5 +64,5 @@ class EstablishTrustStack extends Stack {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
module.exports = {
|
|
67
|
-
|
|
67
|
+
TrustCiStack
|
|
68
68
|
}
|
|
@@ -7,8 +7,7 @@ const { logError, logInfo } = require('../log')
|
|
|
7
7
|
* @typedef {Object} PlatformTemplate
|
|
8
8
|
* @property {string} platformName - Name of platform
|
|
9
9
|
* @property {string} domain - example.com
|
|
10
|
-
* @property {string
|
|
11
|
-
* @property {string[]} supportedEnvironments - qa
|
|
10
|
+
* @property {string} environmentType - local, test, qa, prod
|
|
12
11
|
*
|
|
13
12
|
* @property {string} awsAccountId - Aws account id
|
|
14
13
|
* @property {string=} awsRegion - ?
|
|
@@ -16,10 +15,6 @@ const { logError, logInfo } = require('../log')
|
|
|
16
15
|
* @property {string} awsRoleToAssume - ?
|
|
17
16
|
* @property {string=} awsDeploymentSqsArn - ?
|
|
18
17
|
*
|
|
19
|
-
* @property {string=} ciSubDomain - ?
|
|
20
|
-
* @property {string|mumber=} ciInternalServerPort - ? | number;
|
|
21
|
-
* @property {string=} ciServerName - ?
|
|
22
|
-
* @property {string=} ciDockerNetworkName - ?
|
|
23
18
|
* @property {string} ciGithubActionsRepo - organisation/repoName
|
|
24
19
|
*/
|
|
25
20
|
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-new */
|
|
2
|
-
const { Stack, Duration, RemovalPolicy } = require('aws-cdk-lib')
|
|
3
|
-
const { Queue } = require('aws-cdk-lib/aws-sqs')
|
|
4
|
-
const { Bucket, BucketEncryption, BlockPublicAccess } = require('aws-cdk-lib/aws-s3')
|
|
5
|
-
const { Source, BucketDeployment } = require('aws-cdk-lib/aws-s3-deployment')
|
|
6
|
-
const { nanoid } = require('nanoid')
|
|
7
|
-
|
|
8
|
-
const { ContainerServer } = require('./container-server')
|
|
9
|
-
|
|
10
|
-
const { SupportedDeploymentTypes } = require('../config')
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @class
|
|
14
|
-
*/
|
|
15
|
-
class PlatformStack extends Stack {
|
|
16
|
-
constructor(scope, id, props) {
|
|
17
|
-
super(scope, id, props)
|
|
18
|
-
|
|
19
|
-
if (!props?.config) {
|
|
20
|
-
throw ('[PlatformStack] No template config provided')
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const isContainerDeploymentsEnabled = props.config.supportedDeploymentTypes.includes(SupportedDeploymentTypes.Container)
|
|
24
|
-
|
|
25
|
-
if (isContainerDeploymentsEnabled) {
|
|
26
|
-
|
|
27
|
-
const deploymentQueue = new Queue(this, 'DeploymentQueue', {
|
|
28
|
-
queueName: `${props.config.platformName}-${props.config.activeEnvironment}`,
|
|
29
|
-
receiveMessageWaitTime: Duration.seconds(20)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
const platformConfigBucket = new Bucket(this, 'PlatformConfig', {
|
|
33
|
-
bucketName: `${props.config.platformName}-${props.config.activeEnvironment}-${nanoid().toLowerCase().replaceAll('_', '').replaceAll('-', '')}`,
|
|
34
|
-
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
35
|
-
encryption: BucketEncryption.S3_MANAGED,
|
|
36
|
-
removalPolicy: RemovalPolicy.DESTROY,
|
|
37
|
-
autoDeleteObjects: true
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
const platformConfigDeployment = new BucketDeployment(this, 'PlatformConfigDeployment', {
|
|
41
|
-
sources: [Source.jsonData('platform-config.json', props.config)],
|
|
42
|
-
destinationBucket: platformConfigBucket
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
new ContainerServer(this, 'ContainerServer', {
|
|
46
|
-
platformConfig: props.config,
|
|
47
|
-
platformConfigBucket: platformConfigDeployment.deployedBucket,
|
|
48
|
-
deploymentQueue: deploymentQueue
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
module.exports = {
|
|
57
|
-
PlatformStack
|
|
58
|
-
}
|