@studion/infra-code-blocks 0.0.6 → 0.0.8

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
@@ -30,7 +30,6 @@ import * as studion from '@studion/infra-code-blocks';
30
30
  import * as studion from '@studion/infra-code-blocks';
31
31
 
32
32
  const project = new studion.Project('demo-project', {
33
- environment: 'DEVELOPMENT',
34
33
  services: [
35
34
  {
36
35
  type: 'REDIS',
@@ -76,7 +75,6 @@ type ProjectArgs = {
76
75
  | StaticSiteService
77
76
  | WebServerService
78
77
  )[];
79
- environment: Environment;
80
78
  hostedZoneId?: pulumi.Input<string>;
81
79
  enableSSMConnect?: pulumi.Input<boolean>;
82
80
  };
@@ -85,7 +83,6 @@ type ProjectArgs = {
85
83
  | Argument | Description |
86
84
  | :--------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------: |
87
85
  | services \* | Service list. |
88
- | environment \* | Environment name. |
89
86
  | hostedZoneId | Route53 hosted zone ID responsible for managing records for the domain. |
90
87
  | enableSSMConnect | Setup ec2 instance and SSM in order to connect to the database in the private subnet. Please refer to the [SSM Connect](#ssm-connect) section for more info. |
91
88
 
@@ -101,6 +98,9 @@ type DatabaseService = {
101
98
  allocatedStorage?: pulumi.Input<number>;
102
99
  maxAllocatedStorage?: pulumi.Input<number>;
103
100
  instanceClass?: pulumi.Input<string>;
101
+ tags?: pulumi.Input<{
102
+ [key: string]: pulumi.Input<string>;
103
+ }>;
104
104
  };
105
105
  ```
106
106
 
@@ -118,6 +118,9 @@ export type StaticSiteService = {
118
118
  type: 'STATIC_SITE';
119
119
  serviceName: string;
120
120
  domain: pulumi.Input<string>;
121
+ tags?: pulumi.Input<{
122
+ [key: string]: pulumi.Input<string>;
123
+ }>;
121
124
  };
122
125
  ```
123
126
 
@@ -140,6 +143,9 @@ export type WebServerService = {
140
143
  pulumi.Input<RoleInlinePolicy>[]
141
144
  >;
142
145
  taskRoleInlinePolicies?: pulumi.Input<pulumi.Input<RoleInlinePolicy>[]>;
146
+ tags?: pulumi.Input<{
147
+ [key: string]: pulumi.Input<string>;
148
+ }>;
143
149
  };
144
150
  ```
145
151
 
@@ -370,11 +376,12 @@ The [Database](#database) component deploys a database instance inside a private
370
376
  and it's not publicly accessible from outside of VPC.
371
377
  <br>
372
378
  In order to connect to the database we need to deploy the ec2 instance which will be used
373
- to open an SSH tunnel to the database instance.
379
+ to forward traffic to the database instance.
374
380
  <br>
375
- Because of security reasons, ec2 instance is also deployed inside private subnet
381
+ Because of security reasons, the ec2 instance is also deployed inside a private subnet
376
382
  which means we can't directly connect to it. For that purpose, we use AWS System Manager
377
- which enables us to connect to the ec2 instance even though it's inside private subnet.
383
+ which enables us to connect to the ec2 instance even though it's inside a private subnet.
384
+ The benefit of using AWS SSM is that we don't need a ssh key pair.
378
385
 
379
386
  ![AWS RDS connection schema](/assets/images/ssm-rds.png)
380
387
 
@@ -386,18 +393,6 @@ which enables us to connect to the ec2 instance even though it's inside private
386
393
  $ brew install --cask session-manager-plugin
387
394
  ```
388
395
 
389
- 2. Generate a new ssh key pair or use the existing one.
390
-
391
- ```bash
392
- $ ssh-keygen -f my_rsa
393
- ```
394
-
395
- 3. Set stack config property by running:
396
-
397
- ```bash
398
- $ pulumi config set ssh:publicKey "ssh-rsa Z...9= mymac@Studions-MBP.localdomain"
399
- ```
400
-
401
396
  SSM Connect can be enabled by setting `enableSSMConnect` property to `true`.
402
397
 
403
398
  ```ts
@@ -412,20 +407,13 @@ export const ec2InstanceId = project.ec2SSMConnect?.ec2.id;
412
407
  Open up your terminal and run the following command:
413
408
 
414
409
  ```bash
415
- $ aws ssm start-session --target EC2_INSTANCE_ID --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["22"], "localPortNumber":["9999"]}'
416
- ```
417
-
418
- Where `EC2_INSTANCE_ID` is an ID of the EC2 instance that is created for you. ID can be
419
- obtained by exporting it from the stack.
420
-
421
- Next, open another terminal window and run the following command:
422
-
423
- ```bash
424
- $ ssh ec2-user@localhost -p 9999 -N -L 5555:DATABASE_ADDRESS:DATABASE_PORT -i SSH_PRIVATE_KEY
410
+ $ aws ssm start-session --target EC2_INSTANCE_ID --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"host": ["DATABASE_ADDRESS"], "portNumber":["DATABASE_PORT"], "localPortNumber":["5555"]}'
425
411
  ```
426
412
 
427
- Where `DATABASE_ADDRESS` and `DATABASE_PORT` are the address and port of the database instance,
428
- and `SSH_PRIVATE_KEY` is the path to the SSH private key.
413
+ Where `EC2_INSTANCE_ID` is an ID of the EC2 instance that is created for you
414
+ (ID can be obtained by exporting it from the stack), and
415
+ `DATABASE_ADDRESS` and `DATABASE_PORT` are the address and port of the
416
+ database instance.
429
417
 
430
418
  And that is it! 🥳
431
419
  Now you can use your favorite database client to connect to the database.
@@ -433,9 +421,9 @@ Now you can use your favorite database client to connect to the database.
433
421
  ![RDS connection](/assets/images/rds-connection.png)
434
422
 
435
423
  It is important that for the host you set `localhost` and for the port you set `5555`
436
- because we have an SSH tunnel open that forwards traffic from localhost:5555 to the
437
- DATABASE_ADDRESS:DATABASE_PORT. For the user, password, and database field, set values
438
- which are set in the `Project`.
424
+ because we are port forwarding traffic from
425
+ localhost:5555 to DATABASE_ADDRESS:DATABASE_PORT.
426
+ For the user, password, and database field, set values which are set in the `Project`.
439
427
 
440
428
  ```ts
441
429
  const project = new studion.Project('demo-project', {
@@ -455,4 +443,4 @@ const project = new studion.Project('demo-project', {
455
443
  ## 🚧 TODO
456
444
 
457
445
  - [ ] Add worker service for executing tasks
458
- - [ ] Update docs, describe each service, describe required stack configs...
446
+ - [ ] Add MongoDB service
@@ -29,6 +29,7 @@ class Database extends pulumi.ComponentResource {
29
29
  ],
30
30
  }, { parent: this });
31
31
  this.kms = new aws.kms.Key(`${name}-rds-key`, {
32
+ description: `${name} RDS encryption key`,
32
33
  customerMasterKeySpec: 'SYMMETRIC_DEFAULT',
33
34
  isEnabled: true,
34
35
  keyUsage: 'ENCRYPT_DECRYPT',
@@ -3,7 +3,6 @@ import * as aws from '@pulumi/aws';
3
3
  import * as awsx from '@pulumi/awsx';
4
4
  export type Ec2SSMConnectArgs = {
5
5
  vpc: awsx.ec2.Vpc;
6
- sshPublicKey: pulumi.Input<string>;
7
6
  tags?: pulumi.Input<{
8
7
  [key: string]: pulumi.Input<string>;
9
8
  }>;
@@ -14,6 +13,5 @@ export declare class Ec2SSMConnect extends pulumi.ComponentResource {
14
13
  ec2MessagesVpcEndpoint: aws.ec2.VpcEndpoint;
15
14
  ssmMessagesVpcEndpoint: aws.ec2.VpcEndpoint;
16
15
  ec2: aws.ec2.Instance;
17
- sshKeyPair: aws.ec2.KeyPair;
18
16
  constructor(name: string, args: Ec2SSMConnectArgs, opts?: pulumi.ComponentResourceOptions);
19
17
  }
@@ -56,14 +56,10 @@ class Ec2SSMConnect extends pulumi.ComponentResource {
56
56
  const ssmProfile = new aws.iam.InstanceProfile(`${name}-ssm-profile`, {
57
57
  role: role.name,
58
58
  }, { parent: this, dependsOn: [ssmPolicyAttachment] });
59
- this.sshKeyPair = new aws.ec2.KeyPair(`${name}-ec2-keypair`, {
60
- publicKey: args.sshPublicKey,
61
- }, { parent: this });
62
59
  this.ec2 = new aws.ec2.Instance(`${name}-ec2`, {
63
60
  ami: 'ami-067d1e60475437da2',
64
61
  associatePublicIpAddress: false,
65
62
  instanceType: 't2.micro',
66
- keyName: this.sshKeyPair.keyName,
67
63
  iamInstanceProfile: ssmProfile.name,
68
64
  subnetId,
69
65
  vpcSecurityGroupIds: [this.ec2SecurityGroup.id],
@@ -6,7 +6,6 @@ import { Database, DatabaseArgs } from './database';
6
6
  import { WebServer, WebServerArgs } from './web-server';
7
7
  import { Redis, RedisArgs } from './redis';
8
8
  import { StaticSite, StaticSiteArgs } from './static-site';
9
- import { Environment } from '../constants';
10
9
  import { Ec2SSMConnect } from './ec2-ssm-connect';
11
10
  export type Service = Database | Redis | StaticSite | WebServer;
12
11
  export type Services = Record<string, Service>;
@@ -18,21 +17,19 @@ type ServiceArgs = {
18
17
  };
19
18
  export type DatabaseService = {
20
19
  type: 'DATABASE';
21
- } & ServiceArgs & Omit<DatabaseArgs, 'vpc' | 'tags'>;
20
+ } & ServiceArgs & Omit<DatabaseArgs, 'vpc'>;
22
21
  export type RedisService = {
23
22
  type: 'REDIS';
24
23
  } & ServiceArgs & Pick<RedisArgs, 'dbName' | 'region'>;
25
24
  export type StaticSiteService = {
26
25
  type: 'STATIC_SITE';
27
- } & ServiceArgs & Omit<StaticSiteArgs, 'hostedZoneId' | 'tags'>;
26
+ } & ServiceArgs & Omit<StaticSiteArgs, 'hostedZoneId'>;
28
27
  export type WebServerService = {
29
28
  type: 'WEB_SERVER';
30
29
  environment?: aws.ecs.KeyValuePair[] | ((services: Services) => aws.ecs.KeyValuePair[]);
31
- } & ServiceArgs & Omit<WebServerArgs, 'cluster' | 'vpc' | 'hostedZoneId' | 'environment' | 'tags'>;
32
- export type Environment = (typeof Environment)[keyof typeof Environment];
30
+ } & ServiceArgs & Omit<WebServerArgs, 'cluster' | 'vpc' | 'hostedZoneId' | 'environment'>;
33
31
  export type ProjectArgs = {
34
32
  services: (DatabaseService | RedisService | StaticSiteService | WebServerService)[];
35
- environment: Environment;
36
33
  hostedZoneId?: pulumi.Input<string>;
37
34
  enableSSMConnect?: pulumi.Input<boolean>;
38
35
  };
@@ -41,7 +38,6 @@ export declare class MissingHostedZoneId extends Error {
41
38
  }
42
39
  export declare class Project extends pulumi.ComponentResource {
43
40
  name: string;
44
- environment: Environment;
45
41
  vpc: awsx.ec2.Vpc;
46
42
  cluster?: aws.ecs.Cluster;
47
43
  hostedZoneId?: pulumi.Input<string>;
@@ -33,20 +33,14 @@ class Project extends pulumi.ComponentResource {
33
33
  constructor(name, args, opts = {}) {
34
34
  super('studion:Project', name, {}, opts);
35
35
  this.services = {};
36
- const { services, environment, hostedZoneId } = args;
36
+ const { services, hostedZoneId } = args;
37
37
  this.name = name;
38
38
  this.hostedZoneId = hostedZoneId;
39
- this.environment = environment;
40
39
  this.vpc = this.createVpc();
41
40
  this.createServices(services);
42
41
  if (args.enableSSMConnect) {
43
- const sshConfig = new pulumi.Config('ssh');
44
42
  this.ec2SSMConnect = new ec2_ssm_connect_1.Ec2SSMConnect(`${name}-ssm-connect`, {
45
43
  vpc: this.vpc,
46
- sshPublicKey: sshConfig.require('publicKey'),
47
- tags: {
48
- Env: this.environment,
49
- },
50
44
  });
51
45
  }
52
46
  this.registerOutputs();
@@ -56,9 +50,6 @@ class Project extends pulumi.ComponentResource {
56
50
  numberOfAvailabilityZones: 2,
57
51
  enableDnsHostnames: true,
58
52
  enableDnsSupport: true,
59
- tags: {
60
- Env: this.environment,
61
- },
62
53
  }, { parent: this });
63
54
  return vpc;
64
55
  }
@@ -90,16 +81,11 @@ class Project extends pulumi.ComponentResource {
90
81
  createWebServerPrerequisites() {
91
82
  this.cluster = new aws.ecs.Cluster(`${this.name}-cluster`, {
92
83
  name: this.name,
93
- tags: {
94
- Env: this.environment,
95
- },
96
84
  }, { parent: this });
97
85
  }
98
86
  createDatabaseService(options) {
99
87
  const { serviceName, type } = options, databaseOptions = __rest(options, ["serviceName", "type"]);
100
- const service = new database_1.Database(serviceName, Object.assign(Object.assign({}, databaseOptions), { vpc: this.vpc, tags: {
101
- Env: this.environment,
102
- } }), { parent: this });
88
+ const service = new database_1.Database(serviceName, Object.assign(Object.assign({}, databaseOptions), { vpc: this.vpc }), { parent: this });
103
89
  this.services[serviceName] = service;
104
90
  }
105
91
  createRedisService(options) {
@@ -116,9 +102,7 @@ class Project extends pulumi.ComponentResource {
116
102
  const { serviceName } = options, staticSiteOptions = __rest(options, ["serviceName"]);
117
103
  if (!this.hostedZoneId)
118
104
  throw new MissingHostedZoneId(options.type);
119
- const service = new static_site_1.StaticSite(serviceName, Object.assign(Object.assign({}, staticSiteOptions), { hostedZoneId: this.hostedZoneId, tags: {
120
- Env: this.environment,
121
- } }), { parent: this });
105
+ const service = new static_site_1.StaticSite(serviceName, Object.assign(Object.assign({}, staticSiteOptions), { hostedZoneId: this.hostedZoneId }), { parent: this });
122
106
  this.services[serviceName] = service;
123
107
  }
124
108
  createWebServerService(options) {
@@ -130,9 +114,7 @@ class Project extends pulumi.ComponentResource {
130
114
  const parsedEnv = typeof environment === 'function'
131
115
  ? environment(this.services)
132
116
  : environment;
133
- const service = new web_server_1.WebServer(serviceName, Object.assign(Object.assign({}, ecsOptions), { cluster: this.cluster, vpc: this.vpc, hostedZoneId: this.hostedZoneId, environment: parsedEnv, tags: {
134
- Env: this.environment,
135
- } }), { parent: this });
117
+ const service = new web_server_1.WebServer(serviceName, Object.assign(Object.assign({}, ecsOptions), { cluster: this.cluster, vpc: this.vpc, hostedZoneId: this.hostedZoneId, environment: parsedEnv }), { parent: this });
136
118
  this.services[options.serviceName] = service;
137
119
  }
138
120
  }
@@ -16,7 +16,3 @@ export declare const PredefinedSize: {
16
16
  readonly memory: number;
17
17
  };
18
18
  };
19
- export declare const Environment: {
20
- readonly DEVELOPMENT: "DEVELOPMENT";
21
- readonly PRODUCTION: "PRODUCTION";
22
- };
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Environment = exports.PredefinedSize = void 0;
3
+ exports.PredefinedSize = void 0;
4
4
  const CPU_1_VCPU = 1024;
5
5
  const MEMORY_1GB = 1024;
6
6
  exports.PredefinedSize = {
@@ -21,7 +21,3 @@ exports.PredefinedSize = {
21
21
  memory: MEMORY_1GB * 4, // 4 GB memory
22
22
  },
23
23
  };
24
- exports.Environment = {
25
- DEVELOPMENT: 'DEVELOPMENT',
26
- PRODUCTION: 'PRODUCTION',
27
- };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studion/infra-code-blocks",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Studion common infra components",
5
5
  "keywords": [
6
6
  "infrastructure",