Skip to content

Commit fe38800

Browse files
committed
[#316] Add checkbox type prompt allow select individual module
1 parent 84a9710 commit fe38800

File tree

11 files changed

+106
-40
lines changed

11 files changed

+106
-40
lines changed

.github/wiki/Security.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,3 @@ To add security features to your infrastructure:
2323
1. Run the infrastructure generator
2424
2. Select "Complete infrastructure (VPC + ECR + RDS + S3 + FARGATE + Cloudwatch + Security groups + ALB)" when prompted for infrastructure type
2525
3. Choose "Yes" when asked "Do you want to create (VPC Flow Logs + CloudTrail) to enhance security posture and compliance?"
26-

.tool-versions

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
nodejs 18.12.1
2-
terraform 1.13.3
3-
trivy 0.47.0
2+
terraform 1.14.6
3+
trivy 0.69.2

src/generators/addons/aws/advanced.test.ts

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ describe('AWS advanced template', () => {
2424
provider: 'aws',
2525
infrastructureType: 'advanced',
2626
awsRegion: 'ap-southeast-1',
27+
addonModules: [],
28+
enabledSecurityFeatures: false,
2729
};
2830

2931
beforeAll(async () => {
@@ -74,28 +76,53 @@ describe('AWS advanced template', () => {
7476
});
7577

7678
describe('given enabledSecurityFeatures is true', () => {
77-
const optionsEnabledSecurityFeatures: AwsOptions = {
78-
projectName: projectDir,
79-
provider: 'aws',
80-
infrastructureType: 'advanced',
81-
awsRegion: 'ap-southeast-1',
82-
enabledSecurityFeatures: true,
83-
};
84-
85-
beforeAll(async () => {
86-
jest.clearAllMocks();
87-
await applyAdvancedTemplate(optionsEnabledSecurityFeatures);
79+
describe('given addonModules includes vpcFlowLog', () => {
80+
const optionsEnabledSecurityFeatures: AwsOptions = {
81+
projectName: projectDir,
82+
provider: 'aws',
83+
infrastructureType: 'advanced',
84+
awsRegion: 'ap-southeast-1',
85+
enabledSecurityFeatures: true,
86+
addonModules: ['vpcFlowLog'],
87+
};
88+
89+
beforeAll(async () => {
90+
jest.clearAllMocks();
91+
await applyAdvancedTemplate(optionsEnabledSecurityFeatures);
92+
});
93+
94+
afterAll(() => {
95+
jest.clearAllMocks();
96+
remove('/', projectDir);
97+
});
98+
99+
it('applies VPC Flow Log add-on when flag is set', () => {
100+
expect(applyAwsVpcFlowLog).toHaveBeenCalledWith(
101+
optionsEnabledSecurityFeatures
102+
);
103+
});
88104
});
89-
90-
afterAll(() => {
91-
jest.clearAllMocks();
92-
remove('/', projectDir);
93-
});
94-
95-
it('applies VPC Flow Log add-on when flag is set', () => {
96-
expect(applyAwsVpcFlowLog).toHaveBeenCalledWith(
97-
optionsEnabledSecurityFeatures
98-
);
105+
describe('given addonModules does NOT include vpcFlowLog', () => {
106+
const optionsEnabledSecurityFeaturesWithoutVpcFlowLog: AwsOptions = {
107+
projectName: projectDir,
108+
provider: 'aws',
109+
infrastructureType: 'advanced',
110+
awsRegion: 'ap-southeast-1',
111+
enabledSecurityFeatures: true,
112+
addonModules: [], // No vpcFlowLog
113+
};
114+
115+
afterAll(() => {
116+
jest.clearAllMocks();
117+
remove('/', projectDir);
118+
});
119+
120+
it('does NOT apply VPC Flow Log add-on when flag is set but module is not included', async () => {
121+
await applyAdvancedTemplate(
122+
optionsEnabledSecurityFeaturesWithoutVpcFlowLog
123+
);
124+
expect(applyAwsVpcFlowLog).not.toHaveBeenCalled();
125+
});
99126
});
100127
});
101128
});

src/generators/addons/aws/advanced.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,17 @@ const applyAdvancedTemplate = async (options: AwsOptions) => {
2121
await applyAwsS3(options);
2222
await applyAwsSsm(options);
2323

24-
if (options.enabledSecurityFeatures) {
25-
await applyAwsVpcFlowLog(options);
24+
if (options?.addonModules && options?.addonModules.length > 0) {
25+
await Promise.all(
26+
options.addonModules.map((module) => {
27+
switch (module) {
28+
case 'vpcFlowLog':
29+
return applyAwsVpcFlowLog(options);
30+
default:
31+
throw new Error(`Module ${module} has not been implemented!`);
32+
}
33+
})
34+
);
2635
}
2736
};
2837

src/generators/addons/aws/index.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type AwsOptions = GeneralOptions & {
1616
infrastructureType?: 'blank' | 'advanced';
1717
awsRegion?: string;
1818
enabledSecurityFeatures?: boolean;
19+
addonModules?: string[];
1920
};
2021

2122
const awsChoices = [
@@ -39,11 +40,28 @@ const awsChoices = [
3940
{
4041
type: 'confirm',
4142
name: 'enabledSecurityFeatures',
42-
message:
43-
'Do you want to create (VPC Flow Logs + CloudTrail) to enhance security posture and compliance?',
43+
message: 'Do you want to add more modules(VPC Flow Logs, CloudTrail)?',
4444
default: false,
4545
when: (answers: AwsOptions) => answers.infrastructureType === 'advanced',
4646
},
47+
{
48+
type: 'checkbox',
49+
name: 'addonModules',
50+
message: 'Which security features do you want to add?',
51+
choices: [
52+
{
53+
key: 'vpcFlowLog',
54+
value: 'vpcFlowLog',
55+
name: 'VPC Flow Logs',
56+
},
57+
{
58+
key: 'cloudTrail',
59+
value: 'cloudTrail',
60+
name: 'CloudTrail',
61+
},
62+
],
63+
when: (answers: AwsOptions) => answers.enabledSecurityFeatures,
64+
},
4765
{
4866
type: 'input',
4967
name: 'awsRegion',
@@ -66,7 +84,7 @@ const generateAwsTemplate = async (
6684
...generalOptions,
6785
infrastructureType: awsOptionsPrompt.infrastructureType,
6886
awsRegion: awsOptionsPrompt.awsRegion,
69-
enabledSecurityFeatures: awsOptionsPrompt.enabledSecurityFeatures,
87+
addonModules: awsOptionsPrompt.addonModules,
7088
};
7189

7290
switch (awsOptions.infrastructureType) {

src/generators/addons/aws/modules/vpcFlowLog.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { appendToFile, copy } from '@/helpers/file';
1414

1515
import { AWS_TEMPLATE_PATH } from '../constants';
1616

17-
const vpcFlowLogLocalesContent = dedent`
17+
const vpcFlowLogLocalsContent = dedent`
1818
### Begin VPC Flow Log ###
1919
locals {
2020
vpc_flow_log_s3_bucket_policy = {
@@ -74,14 +74,15 @@ const vpcFlowLogLocalesContent = dedent`
7474
}
7575
]
7676
}
77+
vpc_flow_log_query_year_ranges = "\${formatdate("YYYY", timestamp())},\${formatdate("YYYY", timestamp()) + 5}"
7778
}
7879
### End VPC Flow Log ###`;
7980

8081
const vpcFlowLogVariablesContent = dedent`
8182
variable "vpc_flow_log_retention_days" {
8283
description = "The number of days to retain VPC Flow Logs in S3"
8384
type = number
84-
default = 90
85+
default = 30
8586
}`;
8687

8788
const vpcFlowLogModuleContent = dedent`
@@ -90,7 +91,7 @@ const vpcFlowLogModuleContent = dedent`
9091
9192
env_namespace = local.env_namespace
9293
bucket_name = "\${local.env_namespace}-flow-logs-\${data.aws_caller_identity.current.account_id}"
93-
force_destroy = true
94+
force_destroy = false
9495
object_ownership = "BucketOwnerPreferred"
9596
}
9697
@@ -108,6 +109,7 @@ const vpcFlowLogModuleContent = dedent`
108109
vpc_id = module.vpc.vpc_id
109110
s3_bucket_name = module.s3_flow_log.aws_s3_bucket_name
110111
log_retention_days = var.vpc_flow_log_retention_days
112+
query_year_ranges = local.vpc_flow_log_query_year_ranges
111113
}`;
112114

113115
const applyAwsVpcFlowLog = async (options: AwsOptions) => {
@@ -123,7 +125,7 @@ const applyAwsVpcFlowLog = async (options: AwsOptions) => {
123125
);
124126
appendToFile(
125127
INFRA_CORE_LOCALS_PATH,
126-
vpcFlowLogLocalesContent,
128+
vpcFlowLogLocalsContent,
127129
options.projectName
128130
);
129131
appendToFile(

templates/addons/aws/modules/vpc_flow_log/main.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ resource "aws_glue_catalog_table" "vpc_flow_log_table" {
6565
table_type = "EXTERNAL_TABLE"
6666

6767
storage_descriptor {
68-
location = "s3://${var.s3_bucket_name}/AWSLogs/"
68+
location = "s3://${var.s3_bucket_name}/AWSLogs/${var.s3_key_prefix}/"
6969
input_format = "org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat"
7070
output_format = "org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat"
7171

@@ -106,7 +106,7 @@ resource "aws_glue_catalog_table" "vpc_flow_log_table" {
106106
"projection.aws_region.type" = "enum"
107107
"projection.aws_region.values" = "${data.aws_region.current.region}"
108108
"projection.year.type" = "integer"
109-
"projection.year.range" = "2025,2030" # Update the range as needed
109+
"projection.year.range" = var.query_year_ranges
110110
"projection.year.digits" = "4"
111111
"projection.month.type" = "integer"
112112
"projection.month.range" = "01,12"

templates/addons/aws/modules/vpc_flow_log/variables.tf

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,19 @@ variable "s3_bucket_name" {
1313
type = string
1414
}
1515

16+
variable "s3_key_prefix" {
17+
description = "The prefix for the S3 key to store the flow logs."
18+
type = string
19+
default = ""
20+
}
21+
1622
variable "log_retention_days" {
1723
description = "The number of days to retain the flow logs in S3."
1824
type = number
19-
default = 90
25+
default = 30
26+
}
27+
28+
variable "query_year_ranges" {
29+
description = "The range of years to query in Athena. Format: 'start_year,end_year'. Update the range as needed."
30+
type = string
2031
}

templates/terraform/.tool-versions

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
terraform 1.13.3
2-
trivy 0.47.0
1+
terraform 1.14.6
2+
trivy 0.69.2

templates/terraform/core/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
terraform {
22
# Terraform version
3-
required_version = "1.13.3"
3+
required_version = "1.14.6"
44
}

0 commit comments

Comments
 (0)