Skip to content

Commit

Permalink
[#153] Check modules before applying
Browse files Browse the repository at this point in the history
  • Loading branch information
hoangmirs committed Apr 28, 2023
1 parent 966132b commit b1131d8
Show file tree
Hide file tree
Showing 23 changed files with 300 additions and 107 deletions.
1 change: 1 addition & 0 deletions skeleton/aws/modules/security_group/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// All security groups
1 change: 1 addition & 0 deletions skeleton/aws/modules/security_group/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Outputs for security_group module
2 changes: 1 addition & 1 deletion src/commands/generate/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ describe('Generator command', () => {

it('displays the success message', () => {
expect(stdoutSpy).toHaveBeenCalledWith(
"The infrastructure code was generated at 'aws-advanced-test'\n"
'The infrastructure code was generated at `aws-advanced-test`\n'
);
});
});
Expand Down
25 changes: 15 additions & 10 deletions src/commands/generate/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Args, Command } from '@oclif/core';
import { Args, Command, ux } from '@oclif/core';
import { prompt } from 'inquirer';

import { getProjectPath, remove } from '../../helpers/file';
Expand Down Expand Up @@ -52,14 +52,23 @@ export default class Generator extends Command {
...versionControlChoices,
...providerChoices,
]);

const generalOptions: GeneralOptions = {
projectName: args.projectName,
provider: generalPrompt.provider,
versionControl: generalPrompt.versionControl,
};

await this.generate(generalOptions);

ux.info(
`The infrastructure code was generated at \`${generalOptions.projectName}\``
);
}

private async generate(generalOptions: GeneralOptions) {
try {
this.applyGeneralParts(generalOptions);
await this.applyGeneralParts(generalOptions);

switch (generalOptions.provider) {
case 'aws':
Expand All @@ -71,22 +80,18 @@ export default class Generator extends Command {
}

await this.postProcess(generalOptions);

this.log(
`The infrastructure code was generated at '${generalOptions.projectName}'`
);
} catch (error) {
remove('/', generalOptions.projectName);
console.error(error);
}
}

private applyGeneralParts(generalOptions: GeneralOptions): void {
applyCore(generalOptions);
applyVersionControl(generalOptions);
private async applyGeneralParts(generalOptions: GeneralOptions) {
await applyCore(generalOptions);
await applyVersionControl(generalOptions);
}

private async postProcess(generalOptions: GeneralOptions): Promise<void> {
private async postProcess(generalOptions: GeneralOptions) {
try {
if (await detectTerraform()) {
await formatCode(getProjectPath(generalOptions.projectName));
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,11 @@ const containsContent = (
projectName: string
): boolean => {
const targetPath = getProjectFilePath(target, projectName);

const data = readFileSync(targetPath, 'utf8');
const lines = data.toString().split('\n');
const index = lines.findIndex((line) => line.includes(content));

return lines.includes(content);
return index !== -1;
};

export {
Expand Down
2 changes: 1 addition & 1 deletion src/templates/addons/versionControl/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const versionControlChoices = [
},
];

const applyVersionControl = (generalOptions: GeneralOptions): void => {
const applyVersionControl = async (generalOptions: GeneralOptions) => {
const { versionControl, projectName } = generalOptions;

if (versionControl === 'github') {
Expand Down
28 changes: 21 additions & 7 deletions src/templates/aws/addons/alb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
INFRA_BASE_OUTPUTS_PATH,
INFRA_BASE_VARIABLES_PATH,
} from '../../core/constants';
import { isAWSModuleAdded, requireAWSModules } from '../../core/dependencies';

const albVariablesContent = dedent`
variable "health_check_path" {
Expand Down Expand Up @@ -103,16 +104,29 @@ const albSGOutputsContent = dedent`
value = [aws_security_group.alb.id]
}`;

const applyAlb = ({ projectName }: AwsOptions) => {
copy('aws/modules/alb', 'modules/alb', projectName);
appendToFile(INFRA_BASE_MAIN_PATH, albModuleContent, projectName);
appendToFile(INFRA_BASE_VARIABLES_PATH, albVariablesContent, projectName);
appendToFile(INFRA_BASE_OUTPUTS_PATH, albOutputsContent, projectName);
appendToFile(AWS_SECURITY_GROUP_MAIN_PATH, albSGMainContent, projectName);
const applyAlb = async (options: AwsOptions) => {
if (isAWSModuleAdded('alb', options.projectName)) {
return;
}
await requireAWSModules('alb', 'securityGroup', options);

copy('aws/modules/alb', 'modules/alb', options.projectName);
appendToFile(INFRA_BASE_MAIN_PATH, albModuleContent, options.projectName);
appendToFile(
INFRA_BASE_VARIABLES_PATH,
albVariablesContent,
options.projectName
);
appendToFile(INFRA_BASE_OUTPUTS_PATH, albOutputsContent, options.projectName);
appendToFile(
AWS_SECURITY_GROUP_MAIN_PATH,
albSGMainContent,
options.projectName
);
appendToFile(
AWS_SECURITY_GROUP_OUTPUTS_PATH,
albSGOutputsContent,
projectName
options.projectName
);
};

Expand Down
26 changes: 20 additions & 6 deletions src/templates/aws/addons/bastion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
INFRA_BASE_MAIN_PATH,
INFRA_BASE_VARIABLES_PATH,
} from '../../core/constants';
import { isAWSModuleAdded, requireAWSModules } from '../../core/dependencies';

const bastionVariablesContent = dedent`
variable "bastion_image_id" {
Expand Down Expand Up @@ -88,15 +89,28 @@ const bastionSGOutputsContent = dedent`
value = [aws_security_group.bastion.id]
}`;

const applyBastion = ({ projectName }: AwsOptions) => {
copy('aws/modules/bastion', 'modules/bastion', projectName);
appendToFile(INFRA_BASE_VARIABLES_PATH, bastionVariablesContent, projectName);
appendToFile(INFRA_BASE_MAIN_PATH, bastionModuleContent, projectName);
appendToFile(AWS_SECURITY_GROUP_MAIN_PATH, bastionSGMainContent, projectName);
const applyBastion = async (options: AwsOptions) => {
if (isAWSModuleAdded('bastion', options.projectName)) {
return;
}
await requireAWSModules('bastion', 'securityGroup', options);

copy('aws/modules/bastion', 'modules/bastion', options.projectName);
appendToFile(
INFRA_BASE_VARIABLES_PATH,
bastionVariablesContent,
options.projectName
);
appendToFile(INFRA_BASE_MAIN_PATH, bastionModuleContent, options.projectName);
appendToFile(
AWS_SECURITY_GROUP_MAIN_PATH,
bastionSGMainContent,
options.projectName
);
appendToFile(
AWS_SECURITY_GROUP_OUTPUTS_PATH,
bastionSGOutputsContent,
projectName
options.projectName
);
};

Expand Down
15 changes: 12 additions & 3 deletions src/templates/aws/addons/cloudwatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { dedent } from 'ts-dedent';
import { AwsOptions } from '..';
import { appendToFile, copy } from '../../../helpers/file';
import { INFRA_BASE_MAIN_PATH } from '../../core/constants';
import { isAWSModuleAdded } from '../../core/dependencies';

const cloudwatchModuleContent = dedent`
module "cloudwatch" {
Expand All @@ -11,9 +12,17 @@ const cloudwatchModuleContent = dedent`
namespace = var.namespace
}`;

const applyCloudwatch = ({ projectName }: AwsOptions) => {
copy('aws/modules/cloudwatch', 'modules/cloudwatch', projectName);
appendToFile(INFRA_BASE_MAIN_PATH, cloudwatchModuleContent, projectName);
const applyCloudwatch = async (options: AwsOptions) => {
if (isAWSModuleAdded('log', options.projectName)) {
return;
}

copy('aws/modules/cloudwatch', 'modules/cloudwatch', options.projectName);
appendToFile(
INFRA_BASE_MAIN_PATH,
cloudwatchModuleContent,
options.projectName
);
};

export default applyCloudwatch;
Expand Down
14 changes: 11 additions & 3 deletions src/templates/aws/addons/core/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@ import { AwsOptions } from '../..';
import { copy } from '../../../../helpers/file';
import { INFRA_BASE_PATH, INFRA_SHARED_PATH } from '../../../core/constants';

const applyCommon = ({ projectName }: AwsOptions) => {
copy('aws/providers.tf', `${INFRA_BASE_PATH}/providers.tf`, projectName);
copy('aws/providers.tf', `${INFRA_SHARED_PATH}/providers.tf`, projectName);
const applyCommon = async (options: AwsOptions) => {
copy(
'aws/providers.tf',
`${INFRA_BASE_PATH}/providers.tf`,
options.projectName
);
copy(
'aws/providers.tf',
`${INFRA_SHARED_PATH}/providers.tf`,
options.projectName
);
};

export default applyCommon;
6 changes: 3 additions & 3 deletions src/templates/aws/addons/core/region.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ const regionVariablesContent = (awsRegion: string) => dedent`
default = "${awsRegion}"
}`;

const applyRegion = ({ awsRegion, projectName }: AwsOptions) => {
const applyRegion = async (options: AwsOptions) => {
appendToFile(
INFRA_BASE_VARIABLES_PATH,
regionVariablesContent(awsRegion),
projectName
regionVariablesContent(options.awsRegion),
options.projectName
);
};

Expand Down
25 changes: 21 additions & 4 deletions src/templates/aws/addons/core/securityGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import {
INFRA_BASE_MAIN_PATH,
INFRA_BASE_VARIABLES_PATH,
} from '../../../core/constants';
import {
isAWSModuleAdded,
requireAWSModules,
} from '../../../core/dependencies';

const securityGroupVariablesContent = dedent`
variable "nimble_office_ip" {
Expand All @@ -24,14 +28,27 @@ const securityGroupModuleContent = dedent`
nimble_office_ip = var.nimble_office_ip
}`;

const applySecurityGroup = ({ projectName }: AwsOptions) => {
copy('aws/modules/security_group', 'modules/security_group', projectName);
const applySecurityGroup = async (options: AwsOptions) => {
if (isAWSModuleAdded('securityGroup', options.projectName)) {
return;
}
await requireAWSModules('securityGroup', 'vpc', options);

copy(
'aws/modules/security_group',
'modules/security_group',
options.projectName
);
appendToFile(
INFRA_BASE_VARIABLES_PATH,
securityGroupVariablesContent,
projectName
options.projectName
);
appendToFile(
INFRA_BASE_MAIN_PATH,
securityGroupModuleContent,
options.projectName
);
appendToFile(INFRA_BASE_MAIN_PATH, securityGroupModuleContent, projectName);
};

export default applySecurityGroup;
Expand Down
13 changes: 9 additions & 4 deletions src/templates/aws/addons/core/vpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
INFRA_BASE_MAIN_PATH,
INFRA_BASE_OUTPUTS_PATH,
} from '../../../core/constants';
import { isAWSModuleAdded } from '../../../core/dependencies';

const vpcOutputsContent = dedent`
output "vpc_id" {
Expand All @@ -20,10 +21,14 @@ const vpcModuleContent = dedent`
namespace = var.namespace
}`;

const applyVpc = ({ projectName }: AwsOptions) => {
copy('aws/modules/vpc', 'modules/vpc', projectName);
appendToFile(INFRA_BASE_MAIN_PATH, vpcModuleContent, projectName);
appendToFile(INFRA_BASE_OUTPUTS_PATH, vpcOutputsContent, projectName);
const applyVpc = async (options: AwsOptions) => {
if (isAWSModuleAdded('vpc', options.projectName)) {
return;
}

copy('aws/modules/vpc', 'modules/vpc', options.projectName);
appendToFile(INFRA_BASE_MAIN_PATH, vpcModuleContent, options.projectName);
appendToFile(INFRA_BASE_OUTPUTS_PATH, vpcOutputsContent, options.projectName);
};

export default applyVpc;
Expand Down
17 changes: 13 additions & 4 deletions src/templates/aws/addons/ecr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
INFRA_SHARED_MAIN_PATH,
INFRA_SHARED_VARIABLES_PATH,
} from '../../core/constants';
import { isAWSModuleAdded } from '../../core/dependencies';

const ecrVariablesContent = dedent`
variable "image_limit" {
Expand All @@ -21,10 +22,18 @@ const ecrModuleContent = dedent`
image_limit = var.image_limit
}`;

const applyEcr = ({ projectName }: AwsOptions) => {
copy('aws/modules/ecr', 'modules/ecr', projectName);
appendToFile(INFRA_SHARED_VARIABLES_PATH, ecrVariablesContent, projectName);
appendToFile(INFRA_SHARED_MAIN_PATH, ecrModuleContent, projectName);
const applyEcr = async (options: AwsOptions) => {
if (isAWSModuleAdded('ecr', options.projectName)) {
return;
}

copy('aws/modules/ecr', 'modules/ecr', options.projectName);
appendToFile(
INFRA_SHARED_VARIABLES_PATH,
ecrVariablesContent,
options.projectName
);
appendToFile(INFRA_SHARED_MAIN_PATH, ecrModuleContent, options.projectName);
};

export default applyEcr;
Expand Down
26 changes: 20 additions & 6 deletions src/templates/aws/addons/ecs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
INFRA_BASE_MAIN_PATH,
INFRA_BASE_VARIABLES_PATH,
} from '../../core/constants';
import { isAWSModuleAdded, requireAWSModules } from '../../core/dependencies';

const ecsVariablesContent = dedent`
variable "ecr_repo_name" {
Expand Down Expand Up @@ -148,15 +149,28 @@ const ecsSGOutputsContent = dedent`
value = [aws_security_group.ecs_fargate.id]
}`;

const applyEcs = ({ projectName }: AwsOptions) => {
copy('aws/modules/ecs', 'modules/ecs', projectName);
appendToFile(INFRA_BASE_VARIABLES_PATH, ecsVariablesContent, projectName);
appendToFile(INFRA_BASE_MAIN_PATH, ecsModuleContent, projectName);
appendToFile(AWS_SECURITY_GROUP_MAIN_PATH, ecsSGMainContent, projectName);
const applyEcs = async (options: AwsOptions) => {
if (isAWSModuleAdded('ecs', options.projectName)) {
return;
}
await requireAWSModules('ecs', 'securityGroup', options);

copy('aws/modules/ecs', 'modules/ecs', options.projectName);
appendToFile(
INFRA_BASE_VARIABLES_PATH,
ecsVariablesContent,
options.projectName
);
appendToFile(INFRA_BASE_MAIN_PATH, ecsModuleContent, options.projectName);
appendToFile(
AWS_SECURITY_GROUP_MAIN_PATH,
ecsSGMainContent,
options.projectName
);
appendToFile(
AWS_SECURITY_GROUP_OUTPUTS_PATH,
ecsSGOutputsContent,
projectName
options.projectName
);
};

Expand Down
Loading

0 comments on commit b1131d8

Please sign in to comment.