@ossy/deployment-tools 0.0.64 → 0.0.66
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 +26 -0
- package/cdk.context.json +45 -10
- package/package.json +7 -6
- package/src/cms/cli.js +46 -0
- package/src/config/platform-config.js +4 -1
- package/src/index.cli.js +2 -1
- package/src/infrastructure/container-server/container-server.js +3 -1
- package/src/infrastructure/platform-stack.js +4 -1
package/README.md
CHANGED
|
@@ -39,6 +39,32 @@ npx --yes @ossy/deployment-tools deploy \
|
|
|
39
39
|
|
|
40
40
|
## Infrastructure
|
|
41
41
|
|
|
42
|
+
We use AWS to host our infrastructure and all of it is defined in JavaScript with the help of
|
|
43
|
+
(AWS CDK)[https://aws.amazon.com/cdk/].
|
|
44
|
+
|
|
45
|
+
### Adding a new AWS account
|
|
46
|
+
We have a different account for each service and environment.
|
|
47
|
+
To add a new account follow the steps below.
|
|
48
|
+
|
|
49
|
+
- Create an email group in GoogleAdmin with **public post access**.
|
|
50
|
+
The email should follow the pattern <service-name>-<env>@ossy.se.
|
|
51
|
+
If it's an account for prod use <service-name>@ossy.se.
|
|
52
|
+
Don't forgett to add yourself and other relevant people to the group.
|
|
53
|
+
- Log into our root organisation account and create a new aws account
|
|
54
|
+
with the same naming pattern and email as described above.
|
|
55
|
+
- Log out of the organisation account then send a password reset request to the
|
|
56
|
+
newly created account using the new email.
|
|
57
|
+
- Create a new user in the account with the same name as the account.
|
|
58
|
+
In the same process add the AdministratorAccess managed policy to the user.
|
|
59
|
+
- Create an access key to the account and add it as a (named profile)[https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html] on your computer
|
|
60
|
+
- Create a keypair in the correct region and download it
|
|
61
|
+
- Add the new environment to the platforms.json file in this repository
|
|
62
|
+
- don't forget to add the keypair
|
|
63
|
+
- run the cdk ls command to make sure the new stack is picked up
|
|
64
|
+
- run cdk bootstrap for the account and region. This will create necessary resources like roles used by aws cdk.
|
|
65
|
+
- add the stack name to workflow options
|
|
66
|
+
|
|
67
|
+
|
|
42
68
|
<!-- Deploys AWS infrastructure
|
|
43
69
|
```
|
|
44
70
|
npx --yes @ossy/deployment-tools infrastructure deploy
|
package/cdk.context.json
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
2
|
+
"hosted-zone:account=858451553223:domainName=ossy.se:region=eu-north-1": {
|
|
3
|
+
"Id": "/hostedzone/Z09424571CVOTIJV8Z50C",
|
|
4
|
+
"Name": "ossy.se."
|
|
5
|
+
},
|
|
6
|
+
"vpc-provider:account=858451553223:filter.isDefault=true:region=eu-north-1:returnAsymmetricSubnets=true": {
|
|
7
|
+
"vpcId": "vpc-0298c165cd8861f90",
|
|
8
|
+
"vpcCidrBlock": "172.31.0.0/16",
|
|
9
|
+
"availabilityZones": [],
|
|
10
|
+
"subnetGroups": [
|
|
11
|
+
{
|
|
12
|
+
"name": "Public",
|
|
13
|
+
"type": "Public",
|
|
14
|
+
"subnets": [
|
|
15
|
+
{
|
|
16
|
+
"subnetId": "subnet-06e0c3bfe4895164e",
|
|
17
|
+
"cidr": "172.31.16.0/20",
|
|
18
|
+
"availabilityZone": "eu-north-1a",
|
|
19
|
+
"routeTableId": "rtb-02d1f0d66595c107f"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"subnetId": "subnet-06518594205611f1f",
|
|
23
|
+
"cidr": "172.31.32.0/20",
|
|
24
|
+
"availabilityZone": "eu-north-1b",
|
|
25
|
+
"routeTableId": "rtb-02d1f0d66595c107f"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"subnetId": "subnet-0edc385e74651c812",
|
|
29
|
+
"cidr": "172.31.0.0/20",
|
|
30
|
+
"availabilityZone": "eu-north-1c",
|
|
31
|
+
"routeTableId": "rtb-02d1f0d66595c107f"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"vpc-provider:account=426023801260:filter.isDefault=true:region=eu-north-1:returnAsymmetricSubnets=true": {
|
|
38
|
+
"vpcId": "vpc-07f00a86e35e47534",
|
|
4
39
|
"vpcCidrBlock": "172.31.0.0/16",
|
|
5
40
|
"availabilityZones": [],
|
|
6
41
|
"subnetGroups": [
|
|
@@ -9,29 +44,29 @@
|
|
|
9
44
|
"type": "Public",
|
|
10
45
|
"subnets": [
|
|
11
46
|
{
|
|
12
|
-
"subnetId": "subnet-
|
|
47
|
+
"subnetId": "subnet-0e14b1b1a87fa46db",
|
|
13
48
|
"cidr": "172.31.16.0/20",
|
|
14
49
|
"availabilityZone": "eu-north-1a",
|
|
15
|
-
"routeTableId": "rtb-
|
|
50
|
+
"routeTableId": "rtb-0d999e16443becd03"
|
|
16
51
|
},
|
|
17
52
|
{
|
|
18
|
-
"subnetId": "subnet-
|
|
53
|
+
"subnetId": "subnet-08428891d5e493330",
|
|
19
54
|
"cidr": "172.31.32.0/20",
|
|
20
55
|
"availabilityZone": "eu-north-1b",
|
|
21
|
-
"routeTableId": "rtb-
|
|
56
|
+
"routeTableId": "rtb-0d999e16443becd03"
|
|
22
57
|
},
|
|
23
58
|
{
|
|
24
|
-
"subnetId": "subnet-
|
|
59
|
+
"subnetId": "subnet-02821be03760e8d34",
|
|
25
60
|
"cidr": "172.31.0.0/20",
|
|
26
61
|
"availabilityZone": "eu-north-1c",
|
|
27
|
-
"routeTableId": "rtb-
|
|
62
|
+
"routeTableId": "rtb-0d999e16443becd03"
|
|
28
63
|
}
|
|
29
64
|
]
|
|
30
65
|
}
|
|
31
66
|
]
|
|
32
67
|
},
|
|
33
|
-
"hosted-zone:account=
|
|
34
|
-
"Id": "/hostedzone/
|
|
68
|
+
"hosted-zone:account=426023801260:domainName=ossy.se:region=eu-north-1": {
|
|
69
|
+
"Id": "/hostedzone/Z01074843R7T9G6P0BW11",
|
|
35
70
|
"Name": "ossy.se."
|
|
36
71
|
}
|
|
37
72
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/deployment-tools",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.66",
|
|
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",
|
|
@@ -15,16 +15,17 @@
|
|
|
15
15
|
"bin": "./src/index.cli.js",
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@actions/core": "^1.10.0",
|
|
18
|
-
"@aws-sdk/client-sqs": "^3.
|
|
19
|
-
"@aws-sdk/client-sts": "^3.
|
|
18
|
+
"@aws-sdk/client-sqs": "^3.245.0",
|
|
19
|
+
"@aws-sdk/client-sts": "^3.245.0",
|
|
20
20
|
"arg": "^5.0.2",
|
|
21
|
-
"aws-cdk-lib": "2.
|
|
22
|
-
"constructs": "^10.
|
|
21
|
+
"aws-cdk-lib": "^2.59.0",
|
|
22
|
+
"constructs": "^10.1.211",
|
|
23
23
|
"express": "^4.18.1",
|
|
24
|
+
"nanoid": "^3.3.4",
|
|
24
25
|
"node-fetch": "^2.6.7"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
27
|
-
"aws-cdk": "2.
|
|
28
|
+
"aws-cdk": "^2.59.0",
|
|
28
29
|
"jest": "^27.5.1",
|
|
29
30
|
"jsdoc": "^3.6.11"
|
|
30
31
|
}
|
package/src/cms/cli.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { readFileSync } = require('fs')
|
|
3
|
+
const arg = require('arg')
|
|
4
|
+
const fetch = require('node-fetch')
|
|
5
|
+
const { PlatformDeploymentService } = require('./platform-deployment')
|
|
6
|
+
const { logInfo, logError } = require('../log')
|
|
7
|
+
|
|
8
|
+
const getTokenPayload = token =>
|
|
9
|
+
JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString())
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
const import = options => {
|
|
13
|
+
|
|
14
|
+
const parsedArgs = arg({
|
|
15
|
+
'--authentication': String,
|
|
16
|
+
'--a': '--authentication',
|
|
17
|
+
|
|
18
|
+
'--resource-templates': String,
|
|
19
|
+
'-t': '--resource-templates'
|
|
20
|
+
}, { argv: options })
|
|
21
|
+
|
|
22
|
+
logInfo({ message: '[CMS] reading files' })
|
|
23
|
+
const token = parsedArgs['--authentication']
|
|
24
|
+
const tokenPayload = getTokenPayload(token)
|
|
25
|
+
const templates = readFileSync(resolve(parsedArgs['--resource-templates']), 'utf8')
|
|
26
|
+
|
|
27
|
+
if (!token) return logError({ message: '[CMS] No token provided with --authentication'})
|
|
28
|
+
if (!templates) return logError({ message: '[CMS] No templates provided with --resource-templates'})
|
|
29
|
+
|
|
30
|
+
logInfo({ message: '[CMS] uploading files' })
|
|
31
|
+
|
|
32
|
+
fetch(
|
|
33
|
+
`https://cms.ossy.se/api/v0/workspaces/${tokenPayload?.workspaceId}/resource-templates`,
|
|
34
|
+
{ method: 'POST', headers: { 'Authorization': token }, body: templates }
|
|
35
|
+
)
|
|
36
|
+
.then(() => logInfo({ message: '[CMS] done' }))
|
|
37
|
+
.catch(error => logError({ message: '[CMS] Error', error }))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = {
|
|
41
|
+
handler: ([command, ...options]) => {
|
|
42
|
+
!!command
|
|
43
|
+
? { deploy }[command](options)
|
|
44
|
+
: logError({ message: '[CMS] No command provided' })
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -42,7 +42,10 @@ class PlatformConfigService {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const awsDeploymentSqsArn = `https://sqs.${withDefaults.awsRegion}.amazonaws.com/${withDefaults.awsAccountId}/${withDefaults.platformName}-${withDefaults.activeEnvironment}`
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
const awsRoleToAssume = process.env.CI
|
|
47
|
+
? `github-ci-role-${withDefaults.platformName}`
|
|
48
|
+
: undefined
|
|
46
49
|
|
|
47
50
|
return {
|
|
48
51
|
...withDefaults,
|
package/src/index.cli.js
CHANGED
|
@@ -7,7 +7,8 @@ const loadHandler = {
|
|
|
7
7
|
aws: () => require('./aws-credentials/cli.js'),
|
|
8
8
|
deployment: () => require('./deploy/cli.js'),
|
|
9
9
|
template: () => require('./template/cli.js'),
|
|
10
|
-
server: () => require('./server/cli.js')
|
|
10
|
+
server: () => require('./server/cli.js'),
|
|
11
|
+
cms: () => require('./cms/cli.js')
|
|
11
12
|
}[handlerName]
|
|
12
13
|
|
|
13
14
|
!!loadHandler && loadHandler().handler(restArgs)
|
|
@@ -50,7 +50,9 @@ class ContainerServer extends Construct {
|
|
|
50
50
|
constructor(scope, id, props) {
|
|
51
51
|
super(scope, id)
|
|
52
52
|
|
|
53
|
-
const hostedZone = HostedZone
|
|
53
|
+
const hostedZone = new HostedZone(this, 'HostedZone', {
|
|
54
|
+
zoneName: `${props.platformConfig.activeEnvironment}.${props.platformConfig.domain}`
|
|
55
|
+
})
|
|
54
56
|
|
|
55
57
|
const vpc = Vpc.fromLookup(this, 'VPC', {
|
|
56
58
|
isDefault: true
|
|
@@ -3,6 +3,7 @@ const { Stack, Duration, RemovalPolicy } = require('aws-cdk-lib')
|
|
|
3
3
|
const { Queue } = require('aws-cdk-lib/aws-sqs')
|
|
4
4
|
const { Bucket, BucketEncryption, BlockPublicAccess } = require('aws-cdk-lib/aws-s3')
|
|
5
5
|
const { Source, BucketDeployment } = require('aws-cdk-lib/aws-s3-deployment')
|
|
6
|
+
const { nanoid } = require('nanoid')
|
|
6
7
|
|
|
7
8
|
const { ContainerServer } = require('./container-server')
|
|
8
9
|
|
|
@@ -28,8 +29,10 @@ class PlatformStack extends Stack {
|
|
|
28
29
|
receiveMessageWaitTime: Duration.seconds(20)
|
|
29
30
|
})
|
|
30
31
|
|
|
32
|
+
const bucketName =
|
|
33
|
+
|
|
31
34
|
const platformConfigBucket = new Bucket(this, 'PlatformConfig', {
|
|
32
|
-
bucketName: `${props.config.platformName}-${props.config.activeEnvironment}`,
|
|
35
|
+
bucketName: `${props.config.platformName}-${props.config.activeEnvironment}-${nanoid().toLowerCase().replaceAll('_', '').replaceAll('-', '')}`,
|
|
33
36
|
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
34
37
|
encryption: BucketEncryption.S3_MANAGED,
|
|
35
38
|
removalPolicy: RemovalPolicy.DESTROY,
|