@friggframework/devtools 2.0.0--canary.428.5c4220d.0 → 2.0.0--canary.428.9de98cd.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.
|
@@ -1252,6 +1252,7 @@ class AWSDiscovery {
|
|
|
1252
1252
|
|
|
1253
1253
|
return {
|
|
1254
1254
|
defaultVpcId: vpc.VpcId,
|
|
1255
|
+
vpcCidr: vpc.CidrBlock, // Add VPC CIDR for security group configuration
|
|
1255
1256
|
defaultSecurityGroupId: securityGroup.GroupId,
|
|
1256
1257
|
privateSubnetId1: privateSubnets[0]?.SubnetId,
|
|
1257
1258
|
privateSubnetId2:
|
|
@@ -56,6 +56,7 @@ describe('BuildTimeDiscovery', () => {
|
|
|
56
56
|
describe('discoverAndCreateConfig', () => {
|
|
57
57
|
const mockResources = {
|
|
58
58
|
defaultVpcId: 'vpc-12345678',
|
|
59
|
+
vpcCidr: '172.31.0.0/16',
|
|
59
60
|
defaultSecurityGroupId: 'sg-12345678',
|
|
60
61
|
privateSubnetId1: 'subnet-1',
|
|
61
62
|
privateSubnetId2: 'subnet-2',
|
|
@@ -100,6 +101,7 @@ describe('BuildTimeDiscovery', () => {
|
|
|
100
101
|
describe('replaceTemplateVariables', () => {
|
|
101
102
|
const mockResources = {
|
|
102
103
|
defaultVpcId: 'vpc-12345678',
|
|
104
|
+
vpcCidr: '172.31.0.0/16',
|
|
103
105
|
defaultSecurityGroupId: 'sg-12345678',
|
|
104
106
|
privateSubnetId1: 'subnet-1',
|
|
105
107
|
privateSubnetId2: 'subnet-2',
|
|
@@ -225,6 +227,7 @@ describe('BuildTimeDiscovery', () => {
|
|
|
225
227
|
describe('preBuildHook', () => {
|
|
226
228
|
const mockResources = {
|
|
227
229
|
defaultVpcId: 'vpc-12345678',
|
|
230
|
+
vpcCidr: '172.31.0.0/16',
|
|
228
231
|
defaultSecurityGroupId: 'sg-12345678',
|
|
229
232
|
privateSubnetId1: 'subnet-1',
|
|
230
233
|
privateSubnetId2: 'subnet-2',
|
|
@@ -1050,6 +1050,17 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
1050
1050
|
`Using existing KMS key: ${discoveredResources.defaultKmsKeyId}`
|
|
1051
1051
|
);
|
|
1052
1052
|
|
|
1053
|
+
// Create a CloudFormation-managed alias to track the discovered key
|
|
1054
|
+
// This ensures CloudFormation always has a resource to manage, preventing deletion
|
|
1055
|
+
definition.resources.Resources.FriggKMSKeyAlias = {
|
|
1056
|
+
Type: 'AWS::KMS::Alias',
|
|
1057
|
+
DeletionPolicy: 'Retain',
|
|
1058
|
+
Properties: {
|
|
1059
|
+
AliasName: 'alias/${self:service}-${self:provider.stage}-frigg-kms',
|
|
1060
|
+
TargetKeyId: discoveredResources.defaultKmsKeyId
|
|
1061
|
+
}
|
|
1062
|
+
};
|
|
1063
|
+
|
|
1053
1064
|
definition.provider.iamRoleStatements.push({
|
|
1054
1065
|
Effect: 'Allow',
|
|
1055
1066
|
Action: ['kms:GenerateDataKey', 'kms:Decrypt'],
|
|
@@ -1065,6 +1076,8 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
1065
1076
|
|
|
1066
1077
|
definition.resources.Resources.FriggKMSKey = {
|
|
1067
1078
|
Type: 'AWS::KMS::Key',
|
|
1079
|
+
DeletionPolicy: 'Retain',
|
|
1080
|
+
UpdateReplacePolicy: 'Retain',
|
|
1068
1081
|
Properties: {
|
|
1069
1082
|
EnableKeyRotation: true,
|
|
1070
1083
|
Description: 'Frigg KMS key for field-level encryption',
|
|
@@ -1110,6 +1123,10 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
1110
1123
|
Key: 'Name',
|
|
1111
1124
|
Value: '${self:service}-${self:provider.stage}-frigg-kms-key',
|
|
1112
1125
|
},
|
|
1126
|
+
{
|
|
1127
|
+
Key: 'ManagedBy',
|
|
1128
|
+
Value: 'Frigg',
|
|
1129
|
+
},
|
|
1113
1130
|
{
|
|
1114
1131
|
Key: 'Purpose',
|
|
1115
1132
|
Value: 'Field-level encryption for Frigg application',
|
|
@@ -1118,6 +1135,16 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
1118
1135
|
},
|
|
1119
1136
|
};
|
|
1120
1137
|
|
|
1138
|
+
// Create an alias for the new KMS key for consistent discovery
|
|
1139
|
+
definition.resources.Resources.FriggKMSKeyAlias = {
|
|
1140
|
+
Type: 'AWS::KMS::Alias',
|
|
1141
|
+
DeletionPolicy: 'Retain',
|
|
1142
|
+
Properties: {
|
|
1143
|
+
AliasName: 'alias/${self:service}-${self:provider.stage}-frigg-kms',
|
|
1144
|
+
TargetKeyId: { 'Fn::GetAtt': ['FriggKMSKey', 'Arn'] }
|
|
1145
|
+
}
|
|
1146
|
+
};
|
|
1147
|
+
|
|
1121
1148
|
definition.provider.iamRoleStatements.push({
|
|
1122
1149
|
Effect: 'Allow',
|
|
1123
1150
|
Action: ['kms:GenerateDataKey', 'kms:Decrypt'],
|
|
@@ -2001,6 +2028,13 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
2001
2028
|
AppDefinition.encryption?.fieldLevelEncryptionMethod ===
|
|
2002
2029
|
'kms'
|
|
2003
2030
|
) {
|
|
2031
|
+
// Validate we have VPC CIDR for security group configuration
|
|
2032
|
+
if (!discoveredResources.vpcCidr) {
|
|
2033
|
+
console.warn(
|
|
2034
|
+
'⚠️ Warning: VPC CIDR not discovered. VPC endpoint security group may not work correctly.'
|
|
2035
|
+
);
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2004
2038
|
// Create security group for VPC endpoints if it doesn't exist
|
|
2005
2039
|
if (
|
|
2006
2040
|
!definition.resources.Resources
|
|
@@ -2013,16 +2047,16 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
2013
2047
|
GroupDescription:
|
|
2014
2048
|
'Security group for VPC endpoints',
|
|
2015
2049
|
VpcId: discoveredResources.defaultVpcId,
|
|
2016
|
-
SecurityGroupIngress:
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2050
|
+
SecurityGroupIngress: discoveredResources.vpcCidr
|
|
2051
|
+
? [
|
|
2052
|
+
{
|
|
2053
|
+
IpProtocol: 'tcp',
|
|
2054
|
+
FromPort: 443,
|
|
2055
|
+
ToPort: 443,
|
|
2056
|
+
CidrIp: discoveredResources.vpcCidr, // Use discovered VPC CIDR
|
|
2057
|
+
},
|
|
2058
|
+
]
|
|
2059
|
+
: [], // Empty array if no VPC CIDR discovered
|
|
2026
2060
|
Tags: [
|
|
2027
2061
|
{
|
|
2028
2062
|
Key: 'Name',
|
|
@@ -7,6 +7,7 @@ jest.mock('./aws-discovery', () => {
|
|
|
7
7
|
return {
|
|
8
8
|
discoverResources: jest.fn().mockResolvedValue({
|
|
9
9
|
defaultVpcId: 'vpc-123456',
|
|
10
|
+
vpcCidr: '172.31.0.0/16', // Add VPC CIDR for security group configuration
|
|
10
11
|
defaultSecurityGroupId: 'sg-123456',
|
|
11
12
|
privateSubnetId1: 'subnet-123456',
|
|
12
13
|
privateSubnetId2: 'subnet-789012',
|
|
@@ -398,6 +399,17 @@ describe('composeServerlessDefinition', () => {
|
|
|
398
399
|
expect(result.custom.kmsGrants).toEqual({
|
|
399
400
|
kmsKeyId: 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012'
|
|
400
401
|
});
|
|
402
|
+
|
|
403
|
+
// Check KMS Alias resource is created for discovered key
|
|
404
|
+
expect(result.resources.Resources.FriggKMSKeyAlias).toBeDefined();
|
|
405
|
+
expect(result.resources.Resources.FriggKMSKeyAlias).toEqual({
|
|
406
|
+
Type: 'AWS::KMS::Alias',
|
|
407
|
+
DeletionPolicy: 'Retain',
|
|
408
|
+
Properties: {
|
|
409
|
+
AliasName: 'alias/${self:service}-${self:provider.stage}-frigg-kms',
|
|
410
|
+
TargetKeyId: 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012'
|
|
411
|
+
}
|
|
412
|
+
});
|
|
401
413
|
});
|
|
402
414
|
|
|
403
415
|
it('should create new KMS key when encryption is enabled, no key found, and createResourceIfNoneFound is true', async () => {
|
|
@@ -426,9 +438,11 @@ describe('composeServerlessDefinition', () => {
|
|
|
426
438
|
|
|
427
439
|
const result = await composeServerlessDefinition(appDefinition);
|
|
428
440
|
|
|
429
|
-
// Check that KMS key resource was created
|
|
441
|
+
// Check that KMS key resource was created with DeletionPolicy
|
|
430
442
|
expect(result.resources.Resources.FriggKMSKey).toEqual({
|
|
431
443
|
Type: 'AWS::KMS::Key',
|
|
444
|
+
DeletionPolicy: 'Retain',
|
|
445
|
+
UpdateReplacePolicy: 'Retain',
|
|
432
446
|
Properties: {
|
|
433
447
|
EnableKeyRotation: true,
|
|
434
448
|
Description: 'Frigg KMS key for field-level encryption',
|
|
@@ -471,6 +485,10 @@ describe('composeServerlessDefinition', () => {
|
|
|
471
485
|
Key: 'Name',
|
|
472
486
|
Value: '${self:service}-${self:provider.stage}-frigg-kms-key'
|
|
473
487
|
},
|
|
488
|
+
{
|
|
489
|
+
Key: 'ManagedBy',
|
|
490
|
+
Value: 'Frigg'
|
|
491
|
+
},
|
|
474
492
|
{
|
|
475
493
|
Key: 'Purpose',
|
|
476
494
|
Value: 'Field-level encryption for Frigg application'
|
|
@@ -479,6 +497,17 @@ describe('composeServerlessDefinition', () => {
|
|
|
479
497
|
}
|
|
480
498
|
});
|
|
481
499
|
|
|
500
|
+
// Check KMS Alias resource is created for the new key
|
|
501
|
+
expect(result.resources.Resources.FriggKMSKeyAlias).toBeDefined();
|
|
502
|
+
expect(result.resources.Resources.FriggKMSKeyAlias).toEqual({
|
|
503
|
+
Type: 'AWS::KMS::Alias',
|
|
504
|
+
DeletionPolicy: 'Retain',
|
|
505
|
+
Properties: {
|
|
506
|
+
AliasName: 'alias/${self:service}-${self:provider.stage}-frigg-kms',
|
|
507
|
+
TargetKeyId: { 'Fn::GetAtt': ['FriggKMSKey', 'Arn'] }
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
|
|
482
511
|
// Check IAM permissions for the new key
|
|
483
512
|
const kmsPermission = result.provider.iamRoleStatements.find(
|
|
484
513
|
statement => statement.Action.includes('kms:GenerateDataKey')
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/devtools",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0--canary.428.
|
|
4
|
+
"version": "2.0.0--canary.428.9de98cd.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@aws-sdk/client-ec2": "^3.835.0",
|
|
7
7
|
"@aws-sdk/client-kms": "^3.835.0",
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"@babel/eslint-parser": "^7.18.9",
|
|
10
10
|
"@babel/parser": "^7.25.3",
|
|
11
11
|
"@babel/traverse": "^7.25.3",
|
|
12
|
-
"@friggframework/schemas": "2.0.0--canary.428.
|
|
13
|
-
"@friggframework/test": "2.0.0--canary.428.
|
|
12
|
+
"@friggframework/schemas": "2.0.0--canary.428.9de98cd.0",
|
|
13
|
+
"@friggframework/test": "2.0.0--canary.428.9de98cd.0",
|
|
14
14
|
"@hapi/boom": "^10.0.1",
|
|
15
15
|
"@inquirer/prompts": "^5.3.8",
|
|
16
16
|
"axios": "^1.7.2",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"serverless-http": "^2.7.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@friggframework/eslint-config": "2.0.0--canary.428.
|
|
36
|
-
"@friggframework/prettier-config": "2.0.0--canary.428.
|
|
35
|
+
"@friggframework/eslint-config": "2.0.0--canary.428.9de98cd.0",
|
|
36
|
+
"@friggframework/prettier-config": "2.0.0--canary.428.9de98cd.0",
|
|
37
37
|
"aws-sdk-client-mock": "^4.1.0",
|
|
38
38
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
39
39
|
"jest": "^30.1.3",
|
|
@@ -68,5 +68,5 @@
|
|
|
68
68
|
"publishConfig": {
|
|
69
69
|
"access": "public"
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "9de98cdf6b43272a625ac0ff642f8abda89bb38a"
|
|
72
72
|
}
|