@ttoss/cloud-vpc 0.1.0

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 ADDED
@@ -0,0 +1,34 @@
1
+ # @ttoss/cloud-vpc
2
+
3
+ This module provides a set of resources to create a VPC on AWS.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm install @ttoss/cloud-vpc
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { createVpcTemplate } from '@ttoss/cloud-vpc';
15
+
16
+ const cidrBlock = '10.0.0.0/16';
17
+
18
+ const template = createVpcTemplate({
19
+ cidrBlock,
20
+ });
21
+
22
+ export default template;
23
+ ```
24
+
25
+ ## API
26
+
27
+ ### `createVpcTemplate`
28
+
29
+ Creates a VPC template.
30
+
31
+ #### Parameters
32
+
33
+ - `cidrBlock: string` - The CIDR block of the VPC.
34
+ - `createPublicSubnets: boolean` - Whether to create public subnets. Default is `true`.
@@ -0,0 +1,227 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+
3
+ // src/index.ts
4
+ var NUMBER_OF_AVAILABILITY_ZONES = 3;
5
+ var PUBLIC_ROUTER_TABLE_LOGICAL_ID = "PublicRouteTable";
6
+ var PRIVATE_ROUTER_TABLE_LOGICAL_ID = "PrivateRouteTable";
7
+ var createVpcTemplate = ({
8
+ cidrBlock,
9
+ createPublicSubnets = true
10
+ }) => {
11
+ const totalOfSubnetsOnEachType = 2;
12
+ const getSubnetResource = ({
13
+ number,
14
+ isPublic
15
+ }) => {
16
+ const subnetType = isPublic ? "Public" : "Private";
17
+ const key = `${subnetType}Subnet${number}`;
18
+ const routerTableAssociationKey = `${subnetType}Subnet${number}RouteTableAssociation`;
19
+ const index = (isPublic ? 0 : 1) * totalOfSubnetsOnEachType + number - 1;
20
+ const azIndex = index % NUMBER_OF_AVAILABILITY_ZONES;
21
+ const cidrSubBlockCount = 2 * totalOfSubnetsOnEachType;
22
+ const cidrPrefixLength = parseInt(cidrBlock.split("/")[1], 10);
23
+ const cidrSubBlockBits = 32 - cidrPrefixLength - Math.ceil(Math.log2(cidrSubBlockCount));
24
+ let resources = {
25
+ [key]: {
26
+ Type: "AWS::EC2::Subnet",
27
+ Properties: {
28
+ AvailabilityZone: {
29
+ "Fn::Select": [azIndex, {
30
+ "Fn::GetAZs": ""
31
+ }]
32
+ },
33
+ CidrBlock: {
34
+ "Fn::Select": [index, {
35
+ "Fn::Cidr": [cidrBlock, cidrSubBlockCount, cidrSubBlockBits]
36
+ }]
37
+ },
38
+ MapPublicIpOnLaunch: isPublic,
39
+ VpcId: {
40
+ Ref: "Vpc"
41
+ },
42
+ Tags: [{
43
+ Key: "Name",
44
+ Value: {
45
+ "Fn::Sub": `\${Project}-${subnetType.toLowerCase()}-subnet-${number}-\${AWS::Region}`
46
+ }
47
+ }]
48
+ }
49
+ },
50
+ [routerTableAssociationKey]: {
51
+ Type: "AWS::EC2::SubnetRouteTableAssociation",
52
+ Properties: {
53
+ RouteTableId: {
54
+ Ref: isPublic ? PUBLIC_ROUTER_TABLE_LOGICAL_ID : PRIVATE_ROUTER_TABLE_LOGICAL_ID
55
+ },
56
+ SubnetId: {
57
+ Ref: key
58
+ }
59
+ }
60
+ }
61
+ };
62
+ if (isPublic) {
63
+ resources = {
64
+ ...resources
65
+ };
66
+ }
67
+ if (!isPublic) {
68
+ resources = {
69
+ ...resources
70
+ };
71
+ }
72
+ return resources;
73
+ };
74
+ const template = {
75
+ AWSTemplateFormatVersion: "2010-09-09",
76
+ Description: "VPC, Subnets, and Route Tables for the project.",
77
+ Parameters: {
78
+ Project: {
79
+ Type: "String",
80
+ Description: "The name of the project"
81
+ }
82
+ },
83
+ Resources: {
84
+ Vpc: {
85
+ Type: "AWS::EC2::VPC",
86
+ Properties: {
87
+ CidrBlock: cidrBlock,
88
+ EnableDnsHostnames: true,
89
+ EnableDnsSupport: true,
90
+ Tags: [{
91
+ Key: "Name",
92
+ Value: {
93
+ "Fn::Sub": "${Project}-vpc"
94
+ }
95
+ }]
96
+ }
97
+ },
98
+ ...getSubnetResource({
99
+ number: 1,
100
+ isPublic: false
101
+ }),
102
+ ...getSubnetResource({
103
+ number: 2,
104
+ isPublic: false
105
+ }),
106
+ [PRIVATE_ROUTER_TABLE_LOGICAL_ID]: {
107
+ Type: "AWS::EC2::RouteTable",
108
+ Properties: {
109
+ VpcId: {
110
+ Ref: "Vpc"
111
+ },
112
+ Tags: [{
113
+ Key: "Name",
114
+ Value: {
115
+ "Fn::Sub": "${Project}-private-rtb"
116
+ }
117
+ }]
118
+ }
119
+ }
120
+ },
121
+ Outputs: {
122
+ DefaultSecurityGroup: {
123
+ Description: "The default security group ID",
124
+ Value: {
125
+ "Fn::GetAtt": ["Vpc", "DefaultSecurityGroup"]
126
+ }
127
+ },
128
+ VpcId: {
129
+ Description: "The VPC ID",
130
+ Value: {
131
+ Ref: "Vpc"
132
+ }
133
+ },
134
+ PrivateSubnet1: {
135
+ Description: "The private subnet 1 ID",
136
+ Value: {
137
+ Ref: "PrivateSubnet1"
138
+ }
139
+ },
140
+ PrivateSubnet2: {
141
+ Description: "The private subnet 2 ID",
142
+ Value: {
143
+ Ref: "PrivateSubnet2"
144
+ }
145
+ }
146
+ }
147
+ };
148
+ if (createPublicSubnets) {
149
+ template.Resources = {
150
+ ...template.Resources,
151
+ ...getSubnetResource({
152
+ number: 1,
153
+ isPublic: true
154
+ }),
155
+ ...getSubnetResource({
156
+ number: 2,
157
+ isPublic: true
158
+ }),
159
+ InternetGateway: {
160
+ Type: "AWS::EC2::InternetGateway",
161
+ Properties: {
162
+ Tags: [{
163
+ Key: "Name",
164
+ Value: {
165
+ "Fn::Sub": "${Project}-igw"
166
+ }
167
+ }]
168
+ }
169
+ },
170
+ [PUBLIC_ROUTER_TABLE_LOGICAL_ID]: {
171
+ Type: "AWS::EC2::RouteTable",
172
+ Properties: {
173
+ VpcId: {
174
+ Ref: "Vpc"
175
+ },
176
+ Tags: [{
177
+ Key: "Name",
178
+ Value: {
179
+ "Fn::Sub": "${Project}-public-rtb"
180
+ }
181
+ }]
182
+ }
183
+ },
184
+ InternetGatewayAttachment: {
185
+ Type: "AWS::EC2::VPCGatewayAttachment",
186
+ Properties: {
187
+ InternetGatewayId: {
188
+ Ref: "InternetGateway"
189
+ },
190
+ VpcId: {
191
+ Ref: "Vpc"
192
+ }
193
+ }
194
+ },
195
+ PublicRoute: {
196
+ Type: "AWS::EC2::Route",
197
+ DependsOn: "InternetGatewayAttachment",
198
+ Properties: {
199
+ DestinationCidrBlock: "0.0.0.0/0",
200
+ GatewayId: {
201
+ Ref: "InternetGateway"
202
+ },
203
+ RouteTableId: {
204
+ Ref: PUBLIC_ROUTER_TABLE_LOGICAL_ID
205
+ }
206
+ }
207
+ }
208
+ };
209
+ template.Outputs = {
210
+ ...template.Outputs,
211
+ PublicSubnet1: {
212
+ Description: "The public subnet 1 ID",
213
+ Value: {
214
+ Ref: "PublicSubnet1"
215
+ }
216
+ },
217
+ PublicSubnet2: {
218
+ Description: "The public subnet 2 ID",
219
+ Value: {
220
+ Ref: "PublicSubnet2"
221
+ }
222
+ }
223
+ };
224
+ }
225
+ return template;
226
+ };
227
+ export { createVpcTemplate };
@@ -0,0 +1,8 @@
1
+ import { CloudFormationTemplate } from '@ttoss/cloudformation';
2
+
3
+ declare const createVpcTemplate: ({ cidrBlock, createPublicSubnets, }: {
4
+ cidrBlock: string;
5
+ createPublicSubnets?: boolean;
6
+ }) => CloudFormationTemplate;
7
+
8
+ export { createVpcTemplate };
@@ -0,0 +1,8 @@
1
+ import { CloudFormationTemplate } from '@ttoss/cloudformation';
2
+
3
+ declare const createVpcTemplate: ({ cidrBlock, createPublicSubnets, }: {
4
+ cidrBlock: string;
5
+ createPublicSubnets?: boolean;
6
+ }) => CloudFormationTemplate;
7
+
8
+ export { createVpcTemplate };
package/dist/index.js ADDED
@@ -0,0 +1,259 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ "use strict";
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all) __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
17
+ get: () => from[key],
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
+ });
20
+ }
21
+ return to;
22
+ };
23
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
24
+ value: true
25
+ }), mod);
26
+
27
+ // src/index.ts
28
+ var src_exports = {};
29
+ __export(src_exports, {
30
+ createVpcTemplate: () => createVpcTemplate
31
+ });
32
+ module.exports = __toCommonJS(src_exports);
33
+ var NUMBER_OF_AVAILABILITY_ZONES = 3;
34
+ var PUBLIC_ROUTER_TABLE_LOGICAL_ID = "PublicRouteTable";
35
+ var PRIVATE_ROUTER_TABLE_LOGICAL_ID = "PrivateRouteTable";
36
+ var createVpcTemplate = ({
37
+ cidrBlock,
38
+ createPublicSubnets = true
39
+ }) => {
40
+ const totalOfSubnetsOnEachType = 2;
41
+ const getSubnetResource = ({
42
+ number,
43
+ isPublic
44
+ }) => {
45
+ const subnetType = isPublic ? "Public" : "Private";
46
+ const key = `${subnetType}Subnet${number}`;
47
+ const routerTableAssociationKey = `${subnetType}Subnet${number}RouteTableAssociation`;
48
+ const index = (isPublic ? 0 : 1) * totalOfSubnetsOnEachType + number - 1;
49
+ const azIndex = index % NUMBER_OF_AVAILABILITY_ZONES;
50
+ const cidrSubBlockCount = 2 * totalOfSubnetsOnEachType;
51
+ const cidrPrefixLength = parseInt(cidrBlock.split("/")[1], 10);
52
+ const cidrSubBlockBits = 32 - cidrPrefixLength - Math.ceil(Math.log2(cidrSubBlockCount));
53
+ let resources = {
54
+ [key]: {
55
+ Type: "AWS::EC2::Subnet",
56
+ Properties: {
57
+ AvailabilityZone: {
58
+ "Fn::Select": [azIndex, {
59
+ "Fn::GetAZs": ""
60
+ }]
61
+ },
62
+ CidrBlock: {
63
+ "Fn::Select": [index, {
64
+ "Fn::Cidr": [cidrBlock, cidrSubBlockCount, cidrSubBlockBits]
65
+ }]
66
+ },
67
+ MapPublicIpOnLaunch: isPublic,
68
+ VpcId: {
69
+ Ref: "Vpc"
70
+ },
71
+ Tags: [{
72
+ Key: "Name",
73
+ Value: {
74
+ "Fn::Sub": `\${Project}-${subnetType.toLowerCase()}-subnet-${number}-\${AWS::Region}`
75
+ }
76
+ }]
77
+ }
78
+ },
79
+ [routerTableAssociationKey]: {
80
+ Type: "AWS::EC2::SubnetRouteTableAssociation",
81
+ Properties: {
82
+ RouteTableId: {
83
+ Ref: isPublic ? PUBLIC_ROUTER_TABLE_LOGICAL_ID : PRIVATE_ROUTER_TABLE_LOGICAL_ID
84
+ },
85
+ SubnetId: {
86
+ Ref: key
87
+ }
88
+ }
89
+ }
90
+ };
91
+ if (isPublic) {
92
+ resources = {
93
+ ...resources
94
+ };
95
+ }
96
+ if (!isPublic) {
97
+ resources = {
98
+ ...resources
99
+ };
100
+ }
101
+ return resources;
102
+ };
103
+ const template = {
104
+ AWSTemplateFormatVersion: "2010-09-09",
105
+ Description: "VPC, Subnets, and Route Tables for the project.",
106
+ Parameters: {
107
+ Project: {
108
+ Type: "String",
109
+ Description: "The name of the project"
110
+ }
111
+ },
112
+ Resources: {
113
+ Vpc: {
114
+ Type: "AWS::EC2::VPC",
115
+ Properties: {
116
+ CidrBlock: cidrBlock,
117
+ EnableDnsHostnames: true,
118
+ EnableDnsSupport: true,
119
+ Tags: [{
120
+ Key: "Name",
121
+ Value: {
122
+ "Fn::Sub": "${Project}-vpc"
123
+ }
124
+ }]
125
+ }
126
+ },
127
+ ...getSubnetResource({
128
+ number: 1,
129
+ isPublic: false
130
+ }),
131
+ ...getSubnetResource({
132
+ number: 2,
133
+ isPublic: false
134
+ }),
135
+ [PRIVATE_ROUTER_TABLE_LOGICAL_ID]: {
136
+ Type: "AWS::EC2::RouteTable",
137
+ Properties: {
138
+ VpcId: {
139
+ Ref: "Vpc"
140
+ },
141
+ Tags: [{
142
+ Key: "Name",
143
+ Value: {
144
+ "Fn::Sub": "${Project}-private-rtb"
145
+ }
146
+ }]
147
+ }
148
+ }
149
+ },
150
+ Outputs: {
151
+ DefaultSecurityGroup: {
152
+ Description: "The default security group ID",
153
+ Value: {
154
+ "Fn::GetAtt": ["Vpc", "DefaultSecurityGroup"]
155
+ }
156
+ },
157
+ VpcId: {
158
+ Description: "The VPC ID",
159
+ Value: {
160
+ Ref: "Vpc"
161
+ }
162
+ },
163
+ PrivateSubnet1: {
164
+ Description: "The private subnet 1 ID",
165
+ Value: {
166
+ Ref: "PrivateSubnet1"
167
+ }
168
+ },
169
+ PrivateSubnet2: {
170
+ Description: "The private subnet 2 ID",
171
+ Value: {
172
+ Ref: "PrivateSubnet2"
173
+ }
174
+ }
175
+ }
176
+ };
177
+ if (createPublicSubnets) {
178
+ template.Resources = {
179
+ ...template.Resources,
180
+ ...getSubnetResource({
181
+ number: 1,
182
+ isPublic: true
183
+ }),
184
+ ...getSubnetResource({
185
+ number: 2,
186
+ isPublic: true
187
+ }),
188
+ InternetGateway: {
189
+ Type: "AWS::EC2::InternetGateway",
190
+ Properties: {
191
+ Tags: [{
192
+ Key: "Name",
193
+ Value: {
194
+ "Fn::Sub": "${Project}-igw"
195
+ }
196
+ }]
197
+ }
198
+ },
199
+ [PUBLIC_ROUTER_TABLE_LOGICAL_ID]: {
200
+ Type: "AWS::EC2::RouteTable",
201
+ Properties: {
202
+ VpcId: {
203
+ Ref: "Vpc"
204
+ },
205
+ Tags: [{
206
+ Key: "Name",
207
+ Value: {
208
+ "Fn::Sub": "${Project}-public-rtb"
209
+ }
210
+ }]
211
+ }
212
+ },
213
+ InternetGatewayAttachment: {
214
+ Type: "AWS::EC2::VPCGatewayAttachment",
215
+ Properties: {
216
+ InternetGatewayId: {
217
+ Ref: "InternetGateway"
218
+ },
219
+ VpcId: {
220
+ Ref: "Vpc"
221
+ }
222
+ }
223
+ },
224
+ PublicRoute: {
225
+ Type: "AWS::EC2::Route",
226
+ DependsOn: "InternetGatewayAttachment",
227
+ Properties: {
228
+ DestinationCidrBlock: "0.0.0.0/0",
229
+ GatewayId: {
230
+ Ref: "InternetGateway"
231
+ },
232
+ RouteTableId: {
233
+ Ref: PUBLIC_ROUTER_TABLE_LOGICAL_ID
234
+ }
235
+ }
236
+ }
237
+ };
238
+ template.Outputs = {
239
+ ...template.Outputs,
240
+ PublicSubnet1: {
241
+ Description: "The public subnet 1 ID",
242
+ Value: {
243
+ Ref: "PublicSubnet1"
244
+ }
245
+ },
246
+ PublicSubnet2: {
247
+ Description: "The public subnet 2 ID",
248
+ Value: {
249
+ Ref: "PublicSubnet2"
250
+ }
251
+ }
252
+ };
253
+ }
254
+ return template;
255
+ };
256
+ // Annotate the CommonJS export names for ESM import in node:
257
+ 0 && (module.exports = {
258
+ createVpcTemplate
259
+ });
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@ttoss/cloud-vpc",
3
+ "version": "0.1.0",
4
+ "description": "Deploy a VPC with public and private subnets",
5
+ "author": "ttoss",
6
+ "contributors": [
7
+ "Pedro Arantes <pedro@arantespp.com> (https://arantespp.com)"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/ttoss/ttoss.git",
12
+ "directory": "packages/cloud-vpc"
13
+ },
14
+ "exports": {
15
+ ".": {
16
+ "import": "./dist/esm/index.js",
17
+ "require": "./dist/index.js",
18
+ "types": "./dist/index.d.ts"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "src"
24
+ ],
25
+ "dependencies": {
26
+ "@ttoss/cloudformation": "^0.10.3"
27
+ },
28
+ "devDependencies": {
29
+ "@types/jest": "^29.5.12",
30
+ "jest": "^29.7.0",
31
+ "tsup": "^8.1.0",
32
+ "@ttoss/config": "^1.32.6",
33
+ "@ttoss/test-utils": "^2.1.10"
34
+ },
35
+ "keywords": [
36
+ "aws",
37
+ "cloudformation",
38
+ "vpc"
39
+ ],
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "provenance": true
43
+ },
44
+ "scripts": {
45
+ "build": "tsup",
46
+ "test": "jest --projects tests/unit"
47
+ }
48
+ }