@friggframework/devtools 2.0.0--canary.461.086dedb.0 → 2.0.0--canary.461.322ea57.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.
@@ -137,20 +137,9 @@ class KmsBuilder extends InfrastructureBuilder {
137
137
  },
138
138
  },
139
139
  },
140
- {
141
- Sid: 'AllowLambdaExecutionRole',
142
- Effect: 'Allow',
143
- Principal: {
144
- AWS: { 'Fn::GetAtt': ['IamRoleLambdaExecution', 'Arn'] },
145
- },
146
- Action: [
147
- 'kms:Decrypt',
148
- 'kms:GenerateDataKey',
149
- 'kms:Encrypt',
150
- 'kms:DescribeKey',
151
- ],
152
- Resource: '*',
153
- },
140
+ // NOTE: We do NOT add a statement referencing IamRoleLambdaExecution here
141
+ // because it creates a circular dependency (KMS Key → IAM Role → KMS Key).
142
+ // Instead, IAM policies grant the Lambda execution role permissions to use KMS.
154
143
  ],
155
144
  },
156
145
  Tags: [
@@ -329,15 +329,11 @@ describe('KmsBuilder', () => {
329
329
  const result = await kmsBuilder.build(appDefinition, {});
330
330
 
331
331
  const policy = result.resources.FriggKMSKey.Properties.KeyPolicy;
332
+ // Should NOT have AllowLambdaExecutionRole statement to avoid circular dependency
333
+ // (KMS Key → IAM Role → KMS Key = circular)
334
+ // IAM policies already grant KMS permissions, so key policy doesn't need to reference the role
332
335
  const roleStatement = policy.Statement.find(s => s.Sid === 'AllowLambdaExecutionRole');
333
-
334
- expect(roleStatement).toBeDefined();
335
- expect(roleStatement.Effect).toBe('Allow');
336
- expect(roleStatement.Principal.AWS).toEqual({ 'Fn::GetAtt': ['IamRoleLambdaExecution', 'Arn'] });
337
- expect(roleStatement.Action).toContain('kms:GenerateDataKey');
338
- expect(roleStatement.Action).toContain('kms:Decrypt');
339
- expect(roleStatement.Action).toContain('kms:Encrypt');
340
- expect(roleStatement.Action).toContain('kms:DescribeKey');
336
+ expect(roleStatement).toBeUndefined();
341
337
  });
342
338
  });
343
339
 
@@ -28,7 +28,7 @@ class CloudFormationDiscovery {
28
28
  try {
29
29
  // Try to get the stack
30
30
  const stack = await this.provider.describeStack(stackName);
31
-
31
+
32
32
  // Get stack resources
33
33
  const resources = await this.provider.listStackResources(stackName);
34
34
 
@@ -51,7 +51,7 @@ class CloudFormationDiscovery {
51
51
  if (error.message && error.message.includes('does not exist')) {
52
52
  return null;
53
53
  }
54
-
54
+
55
55
  // Other errors - log and return null
56
56
  console.warn(`⚠️ CloudFormation discovery failed: ${error.message}`);
57
57
  return null;
@@ -73,18 +73,18 @@ class CloudFormationDiscovery {
73
73
 
74
74
  // VPC outputs
75
75
  if (outputMap.VpcId) {
76
- discovered.vpcId = outputMap.VpcId;
76
+ discovered.defaultVpcId = outputMap.VpcId; // VpcBuilder expects 'defaultVpcId'
77
77
  }
78
-
78
+
79
79
  if (outputMap.PrivateSubnetIds) {
80
80
  // Handle comma-separated subnet IDs
81
81
  discovered.privateSubnetIds = outputMap.PrivateSubnetIds.split(',').map(id => id.trim());
82
82
  }
83
-
83
+
84
84
  if (outputMap.PublicSubnetId) {
85
85
  discovered.publicSubnetId = outputMap.PublicSubnetId;
86
86
  }
87
-
87
+
88
88
  if (outputMap.SecurityGroupId) {
89
89
  discovered.securityGroupId = outputMap.SecurityGroupId;
90
90
  }
@@ -116,7 +116,7 @@ class CloudFormationDiscovery {
116
116
  discovered.securityGroupId = PhysicalResourceId;
117
117
  console.log(` ✓ Found security group in stack: ${PhysicalResourceId}`);
118
118
  // Query security group to get VPC ID
119
- if (this.provider && !discovered.vpcId) {
119
+ if (this.provider && !discovered.defaultVpcId) {
120
120
  try {
121
121
  console.log(` Querying security group to get VPC ID...`);
122
122
  const { DescribeSecurityGroupsCommand } = require('@aws-sdk/client-ec2');
@@ -126,8 +126,8 @@ class CloudFormationDiscovery {
126
126
  })
127
127
  );
128
128
  if (sgDetails.SecurityGroups && sgDetails.SecurityGroups.length > 0) {
129
- discovered.vpcId = sgDetails.SecurityGroups[0].VpcId;
130
- console.log(` ✓ Extracted VPC ID from security group: ${discovered.vpcId}`);
129
+ discovered.defaultVpcId = sgDetails.SecurityGroups[0].VpcId; // VpcBuilder expects 'defaultVpcId'
130
+ console.log(` ✓ Extracted VPC ID from security group: ${discovered.defaultVpcId}`);
131
131
  } else {
132
132
  console.warn(` ⚠️ Security group query returned no results`);
133
133
  }
@@ -48,7 +48,7 @@ describe('CloudFormationDiscovery', () => {
48
48
  const result = await cfDiscovery.discoverFromStack('test-stack');
49
49
 
50
50
  expect(result).toEqual({
51
- vpcId: 'vpc-123',
51
+ defaultVpcId: 'vpc-123', // VpcBuilder expects 'defaultVpcId', not 'vpcId'
52
52
  privateSubnetIds: ['subnet-1', 'subnet-2'],
53
53
  publicSubnetId: 'subnet-3',
54
54
  securityGroupId: 'sg-123',
@@ -197,7 +197,7 @@ describe('CloudFormationDiscovery', () => {
197
197
  const result = await cfDiscovery.discoverFromStack('test-stack');
198
198
 
199
199
  expect(result).toEqual({
200
- vpcId: 'vpc-123',
200
+ defaultVpcId: 'vpc-123', // VpcBuilder expects 'defaultVpcId'
201
201
  defaultKmsKeyId: 'arn:aws:kms:us-east-1:123456789:key/abc',
202
202
  auroraClusterId: 'test-cluster',
203
203
  natGatewayId: 'nat-123',
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.461.086dedb.0",
4
+ "version": "2.0.0--canary.461.322ea57.0",
5
5
  "dependencies": {
6
6
  "@aws-sdk/client-ec2": "^3.835.0",
7
7
  "@aws-sdk/client-kms": "^3.835.0",
@@ -11,8 +11,8 @@
11
11
  "@babel/eslint-parser": "^7.18.9",
12
12
  "@babel/parser": "^7.25.3",
13
13
  "@babel/traverse": "^7.25.3",
14
- "@friggframework/schemas": "2.0.0--canary.461.086dedb.0",
15
- "@friggframework/test": "2.0.0--canary.461.086dedb.0",
14
+ "@friggframework/schemas": "2.0.0--canary.461.322ea57.0",
15
+ "@friggframework/test": "2.0.0--canary.461.322ea57.0",
16
16
  "@hapi/boom": "^10.0.1",
17
17
  "@inquirer/prompts": "^5.3.8",
18
18
  "axios": "^1.7.2",
@@ -34,8 +34,8 @@
34
34
  "serverless-http": "^2.7.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@friggframework/eslint-config": "2.0.0--canary.461.086dedb.0",
38
- "@friggframework/prettier-config": "2.0.0--canary.461.086dedb.0",
37
+ "@friggframework/eslint-config": "2.0.0--canary.461.322ea57.0",
38
+ "@friggframework/prettier-config": "2.0.0--canary.461.322ea57.0",
39
39
  "aws-sdk-client-mock": "^4.1.0",
40
40
  "aws-sdk-client-mock-jest": "^4.1.0",
41
41
  "jest": "^30.1.3",
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "086dedb05c8918a9c762c273aef2481ecda7d231"
73
+ "gitHead": "322ea5711e264c07e301f58169414bc67deab2d3"
74
74
  }