@ossy/deployment-tools 0.0.80 → 0.0.82
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/cdk.context.json +8 -0
- package/package.json +1 -1
- package/src/caddy/caddy-config.js +3 -14
- package/src/config/platform-config.js +1 -13
- package/src/deploy/platform-deployment.js +1 -1
- package/src/docker/docker-service.js +6 -8
- package/src/docker/docker-service.playground.js +16 -1
- package/src/infrastructure/container-deployment-target/container-deployment-target.js +11 -3
- package/src/infrastructure/deployment-target-stack.js +0 -1
- package/src/infrastructure/dns-stack.js +4 -10
- package/src/infrastructure/trust-ci-stack.js +9 -3
- package/src/template/deployment-template.js +8 -7
- package/src/template/platform-template.js +0 -2
package/cdk.context.json
CHANGED
|
@@ -68,5 +68,13 @@
|
|
|
68
68
|
"hosted-zone:account=426023801260:domainName=ossy.se:region=eu-north-1": {
|
|
69
69
|
"Id": "/hostedzone/Z01074843R7T9G6P0BW11",
|
|
70
70
|
"Name": "ossy.se."
|
|
71
|
+
},
|
|
72
|
+
"hosted-zone:account=858451553223:domainName=oskarssylwan.se:region=eu-north-1": {
|
|
73
|
+
"Id": "/hostedzone/Z06541531WYSO7D1IVDTT",
|
|
74
|
+
"Name": "oskarssylwan.se."
|
|
75
|
+
},
|
|
76
|
+
"hosted-zone:account=858451553223:domainName=oskarssylwan.com:region=eu-north-1": {
|
|
77
|
+
"Id": "/hostedzone/Z07488011P8FXGWA11LTS",
|
|
78
|
+
"Name": "oskarssylwan.com."
|
|
71
79
|
}
|
|
72
80
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/deployment-tools",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.82",
|
|
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",
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const { DeploymentTemplateService } = require('../template')
|
|
2
|
-
const { SupportedEnvironments } = require('../config')
|
|
3
2
|
|
|
4
3
|
const Matchers = {
|
|
5
4
|
host: host => ({ host: [host] }),
|
|
@@ -25,7 +24,7 @@ class CaddyConfigService {
|
|
|
25
24
|
static createConfig(platformConfig, deploymentTemplates) {
|
|
26
25
|
|
|
27
26
|
const containerDeployments = DeploymentTemplateService
|
|
28
|
-
.
|
|
27
|
+
.getContainerDeployments(deploymentTemplates)
|
|
29
28
|
|
|
30
29
|
return {
|
|
31
30
|
apps: {
|
|
@@ -40,21 +39,11 @@ class CaddyConfigService {
|
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
},
|
|
43
|
-
tls:
|
|
42
|
+
tls: {
|
|
44
43
|
automation: {
|
|
45
44
|
policies: [
|
|
46
45
|
{
|
|
47
|
-
subjects:
|
|
48
|
-
.flatMap(rootDomain => {
|
|
49
|
-
const environmentSubdomain = platformConfig.environmentType === SupportedEnvironments.PROD
|
|
50
|
-
? ''
|
|
51
|
-
: `${platformConfig.environmentType}.`
|
|
52
|
-
|
|
53
|
-
return [
|
|
54
|
-
`*.${environmentSubdomain}${rootDomain}`,
|
|
55
|
-
`${environmentSubdomain}${rootDomain}`
|
|
56
|
-
]
|
|
57
|
-
}),
|
|
46
|
+
subjects: containerDeployments.map(({ domain }) => domain),
|
|
58
47
|
issuers:[
|
|
59
48
|
{
|
|
60
49
|
challenges: {
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Platform config definition
|
|
3
3
|
* @typedef {Object} PlatformConfig
|
|
4
4
|
* @property {string} platformName - Name of platform
|
|
5
|
-
* @property {string} environmentType - local, test, qa, prod
|
|
6
5
|
* @property {object} dnsRecords - map of dns records by root domain, only supports MX records so that we can add dns records for our email service
|
|
7
6
|
*
|
|
8
7
|
* @property {string} awsAccountId - Aws account id
|
|
@@ -20,14 +19,6 @@ const SupportedRegions = {
|
|
|
20
19
|
North: 'eu-north-1'
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
const SupportedEnvironments = {
|
|
24
|
-
LOCAL: 'local',
|
|
25
|
-
QA: 'qa',
|
|
26
|
-
TEST: 'test',
|
|
27
|
-
DEMO: 'demo',
|
|
28
|
-
PROD: 'prod'
|
|
29
|
-
}
|
|
30
|
-
|
|
31
22
|
const SupportedDeploymentTypes = {
|
|
32
23
|
Container: 'CONTAINER',
|
|
33
24
|
Static: 'STATIC'
|
|
@@ -41,9 +32,7 @@ class PlatformConfigService {
|
|
|
41
32
|
static from(template) {
|
|
42
33
|
|
|
43
34
|
const withDefaults = {
|
|
44
|
-
platformName:
|
|
45
|
-
domain: 'localhost',
|
|
46
|
-
environmentType: SupportedEnvironments.LOCAL,
|
|
35
|
+
platformName: 'local',
|
|
47
36
|
awsRegion: SupportedRegions.North,
|
|
48
37
|
...template,
|
|
49
38
|
// values below should not be overriden by the template properties
|
|
@@ -68,6 +57,5 @@ class PlatformConfigService {
|
|
|
68
57
|
module.exports = {
|
|
69
58
|
PlatformConfigService,
|
|
70
59
|
SupportedRegions,
|
|
71
|
-
SupportedEnvironments,
|
|
72
60
|
SupportedDeploymentTypes
|
|
73
61
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { readFileSync } = require('fs')
|
|
2
2
|
const { resolve } = require('path')
|
|
3
3
|
const { PlatformTemplateService, DeploymentTemplateService } = require('../template')
|
|
4
|
-
const { PlatformConfigService, SupportedDeploymentTypes
|
|
4
|
+
const { PlatformConfigService, SupportedDeploymentTypes } = require('../config')
|
|
5
5
|
const { DeploymentQueueService } = require('../deployment-queue')
|
|
6
6
|
const { CaddyConfigService } = require('../caddy')
|
|
7
7
|
const { logError } = require('../log')
|
|
@@ -26,9 +26,8 @@ class DockerService {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
static stopContainer(deploymentRequest) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return exec(`docker stop ${name}`)
|
|
29
|
+
logInfo({ message: `[DockerService] Stopping container for ${deploymentRequest.domain}` })
|
|
30
|
+
return exec(`docker stop ${deploymentRequest.domain}`)
|
|
32
31
|
.catch(() => {}) // no worries if container isn't there
|
|
33
32
|
}
|
|
34
33
|
|
|
@@ -40,12 +39,11 @@ class DockerService {
|
|
|
40
39
|
.catch(() => {}) // no worries if container isn't there
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
static startContainer(platformConfig, { image, containerPort, hostPort, registry, env }) {
|
|
44
|
-
const name = image.replaceAll('/', '_')
|
|
42
|
+
static startContainer(platformConfig, { image, containerPort, hostPort, registry, env, domain }) {
|
|
45
43
|
const imageUrl = !!registry ? `${registry}/${image}` : image
|
|
46
|
-
const envsAsString = Object.entries(env || {}).reduce((envs, [name, value]) => `${envs} --env ${name}
|
|
47
|
-
logInfo({ message: `[DockerService]
|
|
48
|
-
return exec(`docker run -d -p ${hostPort}:${containerPort} --name=${
|
|
44
|
+
const envsAsString = Object.entries(env || {}).reduce((envs, [name, value]) => `${envs} --env ${name}="${value}"`, '')
|
|
45
|
+
logInfo({ message: `[DockerService] Starting container for ${domain} with port mapping ${hostPort}:${containerPort} and source ${imageUrl}` })
|
|
46
|
+
return exec(`docker run -d -p ${hostPort}:${containerPort} --name=${domain} --network=${platformConfig.ciDockerNetworkName} --network-alias=${domain} --rm ${envsAsString} ${imageUrl}`)
|
|
49
47
|
.catch(logErrorAndReject(`[DockerService] Could not start container ${image}`))
|
|
50
48
|
}
|
|
51
49
|
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
const { DockerService } = require('./docker-service')
|
|
2
2
|
|
|
3
|
+
const platformConfig = {
|
|
4
|
+
ciDockerNetworkName: 'foo'
|
|
5
|
+
}
|
|
3
6
|
|
|
4
|
-
|
|
7
|
+
const deploymentTemplate = {
|
|
8
|
+
"domain": "api.qa.ossy.se",
|
|
9
|
+
"image": "ossy-se/cms-api",
|
|
10
|
+
"targetDeploymentPlatform": "ossybot",
|
|
11
|
+
"type": "CONTAINER",
|
|
12
|
+
"hostPort": "3001",
|
|
13
|
+
"containerPort": "3000",
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
DockerService.startContainer(
|
|
17
|
+
platformConfig,
|
|
18
|
+
deploymentTemplate
|
|
19
|
+
)
|
|
@@ -10,7 +10,9 @@ const {
|
|
|
10
10
|
SecurityGroup,
|
|
11
11
|
Peer,
|
|
12
12
|
Port,
|
|
13
|
-
UserData
|
|
13
|
+
UserData,
|
|
14
|
+
BlockDevice,
|
|
15
|
+
BlockDeviceVolume
|
|
14
16
|
} = require('aws-cdk-lib/aws-ec2')
|
|
15
17
|
const { Role, ServicePrincipal, Policy, PolicyStatement, Effect } = require('aws-cdk-lib/aws-iam')
|
|
16
18
|
const { Queue } = require('aws-cdk-lib/aws-sqs')
|
|
@@ -73,7 +75,7 @@ class ContainerDeploymentTarget extends Construct {
|
|
|
73
75
|
})
|
|
74
76
|
|
|
75
77
|
const platformConfigDeployment = new BucketDeployment(this, 'PlatformConfigDeployment', {
|
|
76
|
-
sources: [Source.jsonData('platform-config.json', props.config)],
|
|
78
|
+
sources: [Source.jsonData('platform-config.json', { ...props.config, awsRoleToAssume: undefined })],
|
|
77
79
|
destinationBucket: props.bucket
|
|
78
80
|
})
|
|
79
81
|
|
|
@@ -143,11 +145,17 @@ class ContainerDeploymentTarget extends Construct {
|
|
|
143
145
|
role,
|
|
144
146
|
instanceType: InstanceType.of(
|
|
145
147
|
InstanceClass.T3,
|
|
146
|
-
InstanceSize.
|
|
148
|
+
InstanceSize.LARGE
|
|
147
149
|
),
|
|
148
150
|
machineImage: new GenericLinuxImage({
|
|
149
151
|
[SupportedRegions.North]: InstanceImages.UBUNTU
|
|
150
152
|
}),
|
|
153
|
+
blockDevices: [
|
|
154
|
+
{
|
|
155
|
+
deviceName: '/dev/sda1',
|
|
156
|
+
volume: BlockDeviceVolume.ebs(50)
|
|
157
|
+
}
|
|
158
|
+
],
|
|
151
159
|
keyName: props.config.awsKeyPairName
|
|
152
160
|
})
|
|
153
161
|
|
|
@@ -5,7 +5,7 @@ const {
|
|
|
5
5
|
MxRecord,
|
|
6
6
|
RecordTarget
|
|
7
7
|
} = require('aws-cdk-lib/aws-route53')
|
|
8
|
-
const { SupportedDeploymentTypes
|
|
8
|
+
const { SupportedDeploymentTypes } = require('../config')
|
|
9
9
|
const { DeploymentTemplateService } = require('../template')
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -34,22 +34,16 @@ class DnsStack extends Stack {
|
|
|
34
34
|
constructor(scope, id, props) {
|
|
35
35
|
super(scope, id, props)
|
|
36
36
|
|
|
37
|
-
if (props.config.environmentType === SupportedEnvironments.PROD) {
|
|
38
|
-
// const isDomainForCorrectEnvironment = !Object.values(SupportedEnvironments)
|
|
39
|
-
// .find(env => deployment.domain.includes(env))
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
|
|
43
37
|
const containerDeployments = DeploymentTemplateService
|
|
44
|
-
.
|
|
38
|
+
.getContainerDeployments(props.deployments)
|
|
45
39
|
|
|
46
40
|
DeploymentTemplateService
|
|
47
41
|
.groupDeploymentDomainsByRootDomain(containerDeployments)
|
|
48
42
|
.forEach((domains, rootDomain) => {
|
|
49
|
-
const zone =
|
|
43
|
+
const zone = HostedZone.fromLookup(this, `${rootDomain}-zone`, { domainName: rootDomain })
|
|
50
44
|
|
|
51
45
|
domains.forEach(domain => {
|
|
52
|
-
new ARecord(this, domain
|
|
46
|
+
new ARecord(this, `${domain}-record`, {
|
|
53
47
|
zone,
|
|
54
48
|
recordName: domain,
|
|
55
49
|
target: RecordTarget.fromIpAddresses(props.containerDeploymentTargetPublicIp),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { Stack, Duration } = require('aws-cdk-lib')
|
|
1
|
+
const { Stack, Duration, CfnOutput } = require('aws-cdk-lib')
|
|
2
2
|
const {
|
|
3
3
|
OpenIdConnectProvider,
|
|
4
4
|
OpenIdConnectPrincipal,
|
|
@@ -41,10 +41,9 @@ class TrustCiStack extends Stack {
|
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
// eslint-disable-next-line no-new
|
|
44
|
-
new Role(this, 'GitHubActionsRole', {
|
|
44
|
+
const role = new Role(this, 'GitHubActionsRole', {
|
|
45
45
|
assumedBy: GitHubPrincipal,
|
|
46
46
|
description: 'Role assumed by GitHubPrincipal for deploying from CI using aws cdk',
|
|
47
|
-
roleName: props.config.awsRoleToAssume,
|
|
48
47
|
maxSessionDuration: Duration.hours(1),
|
|
49
48
|
inlinePolicies: {
|
|
50
49
|
CdkDeploymentPolicy: new PolicyDocument({
|
|
@@ -62,6 +61,13 @@ class TrustCiStack extends Stack {
|
|
|
62
61
|
})
|
|
63
62
|
}
|
|
64
63
|
})
|
|
64
|
+
|
|
65
|
+
new CfnOutput(this, 'CiAwsRoleToAssume', {
|
|
66
|
+
value: role.roleName,
|
|
67
|
+
description: 'Name of role to be assumed in CI/CD pipelines on github',
|
|
68
|
+
exportName: 'awsRoleToAssume'
|
|
69
|
+
})
|
|
70
|
+
|
|
65
71
|
}
|
|
66
72
|
}
|
|
67
73
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { glob } = require('glob')
|
|
2
2
|
const { readFileSync } = require('fs')
|
|
3
3
|
const { logError, logInfo } = require('../log')
|
|
4
|
-
const { SupportedDeploymentTypes
|
|
4
|
+
const { SupportedDeploymentTypes } = require('../config')
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Deployment template definition
|
|
@@ -32,6 +32,11 @@ class DeploymentTemplateService {
|
|
|
32
32
|
.then(filePaths => filePaths
|
|
33
33
|
.map(path => readFileSync(path, 'utf-8'))
|
|
34
34
|
.flatMap(json => JSON.parse(json))
|
|
35
|
+
.map(deploymentTemplate => ({
|
|
36
|
+
containerPort: '3000',
|
|
37
|
+
registry: 'ghcr.io',
|
|
38
|
+
...deploymentTemplate
|
|
39
|
+
}))
|
|
35
40
|
.reduce((deploymentsMap, deployment) => {
|
|
36
41
|
if (!!deploymentsMap[deployment.targetDeploymentPlatform]) {
|
|
37
42
|
return {
|
|
@@ -52,13 +57,9 @@ class DeploymentTemplateService {
|
|
|
52
57
|
)
|
|
53
58
|
}
|
|
54
59
|
|
|
55
|
-
static
|
|
60
|
+
static getContainerDeployments(deployments) {
|
|
56
61
|
return deployments
|
|
57
|
-
.filter(deployment =>
|
|
58
|
-
const isContainerDeployment = deployment.type === SupportedDeploymentTypes.Container
|
|
59
|
-
const isDomainForCorrectEnvironment = deployment.domain.includes(environmentType)
|
|
60
|
-
return isContainerDeployment && isDomainForCorrectEnvironment
|
|
61
|
-
})
|
|
62
|
+
.filter(deployment => deployment.type === SupportedDeploymentTypes.Container)
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
static groupDeploymentDomainsByRootDomain(deployments) {
|
|
@@ -6,8 +6,6 @@ const { logError, logInfo } = require('../log')
|
|
|
6
6
|
* Platform template definition
|
|
7
7
|
* @typedef {Object} PlatformTemplate
|
|
8
8
|
* @property {string} platformName - Name of platform
|
|
9
|
-
* @property {string} domain - example.com
|
|
10
|
-
* @property {string} environmentType - local, test, qa, prod
|
|
11
9
|
*
|
|
12
10
|
* @property {string} awsAccountId - Aws account id
|
|
13
11
|
* @property {string=} awsRegion - ?
|