@friggframework/devtools 2.0.0--canary.428.db65660.0 → 2.0.0--canary.428.2b9210c.1

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.
@@ -1680,6 +1680,8 @@ const composeServerlessDefinition = async (AppDefinition) => {
1680
1680
  if (!useExistingEip) {
1681
1681
  definition.resources.Resources.FriggNATGatewayEIP = {
1682
1682
  Type: 'AWS::EC2::EIP',
1683
+ DeletionPolicy: 'Retain', // Prevent accidental deletion
1684
+ UpdateReplacePolicy: 'Retain', // Prevent replacement during updates
1683
1685
  Properties: {
1684
1686
  Domain: 'vpc',
1685
1687
  Tags: [
@@ -1808,6 +1810,8 @@ const composeServerlessDefinition = async (AppDefinition) => {
1808
1810
  // Create NAT Gateway only if not reusing existing one
1809
1811
  definition.resources.Resources.FriggNATGateway = {
1810
1812
  Type: 'AWS::EC2::NatGateway',
1813
+ DeletionPolicy: 'Retain', // Prevent accidental deletion
1814
+ UpdateReplacePolicy: 'Retain', // Prevent replacement during updates
1811
1815
  Properties: {
1812
1816
  AllocationId: useExistingEip ?
1813
1817
  discoveredResources.existingElasticIpAllocationId :
@@ -1904,11 +1908,15 @@ const composeServerlessDefinition = async (AppDefinition) => {
1904
1908
  }
1905
1909
  }
1906
1910
 
1907
- // Always add route table and routes (referencing the NAT, whether new or existing)
1908
- // IMPORTANT: Create a new route table to ensure clean routing configuration
1909
- // This avoids issues with stale routes pointing to deleted NAT Gateways
1911
+ // ALWAYS create the route table resource in CloudFormation for consistency
1912
+ // Use DeletionPolicy: Retain to prevent deletion when removed from template
1913
+ // This ensures CloudFormation maintains consistent state management
1914
+ console.log('Setting up route table for Lambda subnets');
1915
+
1910
1916
  definition.resources.Resources.FriggLambdaRouteTable = {
1911
1917
  Type: 'AWS::EC2::RouteTable',
1918
+ DeletionPolicy: 'Retain', // Critical: Prevents deletion when resource is removed
1919
+ UpdateReplacePolicy: 'Retain', // Prevents replacement during stack updates
1912
1920
  Properties: {
1913
1921
  VpcId: discoveredResources.defaultVpcId || {
1914
1922
  Ref: 'FriggVPC',
@@ -1922,10 +1930,21 @@ const composeServerlessDefinition = async (AppDefinition) => {
1922
1930
  Key: 'ManagedBy',
1923
1931
  Value: 'Frigg',
1924
1932
  },
1933
+ {
1934
+ Key: 'Environment',
1935
+ Value: '${self:provider.stage}',
1936
+ },
1937
+ {
1938
+ Key: 'Service',
1939
+ Value: '${self:service}',
1940
+ },
1925
1941
  ],
1926
1942
  },
1927
1943
  };
1928
1944
 
1945
+ // Always use CloudFormation reference for consistency
1946
+ const routeTableId = { Ref: 'FriggLambdaRouteTable' };
1947
+
1929
1948
  // Determine which NAT Gateway ID to use for routing
1930
1949
  let natGatewayIdForRoute;
1931
1950
 
@@ -1956,13 +1975,15 @@ const composeServerlessDefinition = async (AppDefinition) => {
1956
1975
  );
1957
1976
  }
1958
1977
 
1959
- // Only create NAT route if we have a NAT Gateway
1978
+ // ALWAYS create/update NAT route if we have a NAT Gateway
1979
+ // This ensures routes are always correct even if NAT Gateway changes
1960
1980
  if (natGatewayIdForRoute) {
1961
- console.log(`Creating NAT route: 0.0.0.0/0 → ${natGatewayIdForRoute}`);
1981
+ console.log(`Configuring NAT route: 0.0.0.0/0 → ${natGatewayIdForRoute}`);
1962
1982
  definition.resources.Resources.FriggNATRoute = {
1963
1983
  Type: 'AWS::EC2::Route',
1984
+ DependsOn: 'FriggLambdaRouteTable',
1964
1985
  Properties: {
1965
- RouteTableId: { Ref: 'FriggLambdaRouteTable' },
1986
+ RouteTableId: routeTableId,
1966
1987
  DestinationCidrBlock: '0.0.0.0/0',
1967
1988
  NatGatewayId: natGatewayIdForRoute,
1968
1989
  },
@@ -1979,13 +2000,15 @@ const composeServerlessDefinition = async (AppDefinition) => {
1979
2000
  // CloudFormation will automatically disassociate from old route table first
1980
2001
  }
1981
2002
 
2003
+ // ALWAYS create subnet associations to ensure correct routing
2004
+ // CloudFormation will handle existing associations gracefully
1982
2005
  // Only create associations for discovered subnets (not for Refs)
1983
2006
  if (typeof vpcConfig.subnetIds[0] === 'string') {
1984
2007
  definition.resources.Resources.FriggSubnet1RouteAssociation = {
1985
2008
  Type: 'AWS::EC2::SubnetRouteTableAssociation',
1986
2009
  Properties: {
1987
2010
  SubnetId: vpcConfig.subnetIds[0],
1988
- RouteTableId: { Ref: 'FriggLambdaRouteTable' },
2011
+ RouteTableId: routeTableId,
1989
2012
  },
1990
2013
  DependsOn: 'FriggLambdaRouteTable',
1991
2014
  };
@@ -1996,7 +2019,7 @@ const composeServerlessDefinition = async (AppDefinition) => {
1996
2019
  Type: 'AWS::EC2::SubnetRouteTableAssociation',
1997
2020
  Properties: {
1998
2021
  SubnetId: vpcConfig.subnetIds[1],
1999
- RouteTableId: { Ref: 'FriggLambdaRouteTable' },
2022
+ RouteTableId: routeTableId,
2000
2023
  },
2001
2024
  DependsOn: 'FriggLambdaRouteTable',
2002
2025
  };
@@ -2008,7 +2031,7 @@ const composeServerlessDefinition = async (AppDefinition) => {
2008
2031
  Type: 'AWS::EC2::SubnetRouteTableAssociation',
2009
2032
  Properties: {
2010
2033
  SubnetId: vpcConfig.subnetIds[0],
2011
- RouteTableId: { Ref: 'FriggLambdaRouteTable' },
2034
+ RouteTableId: routeTableId,
2012
2035
  },
2013
2036
  DependsOn: ['FriggLambdaRouteTable', vpcConfig.subnetIds[0].Ref],
2014
2037
  };
@@ -2019,13 +2042,14 @@ const composeServerlessDefinition = async (AppDefinition) => {
2019
2042
  Type: 'AWS::EC2::SubnetRouteTableAssociation',
2020
2043
  Properties: {
2021
2044
  SubnetId: vpcConfig.subnetIds[1],
2022
- RouteTableId: { Ref: 'FriggLambdaRouteTable' },
2045
+ RouteTableId: routeTableId,
2023
2046
  },
2024
2047
  DependsOn: ['FriggLambdaRouteTable', vpcConfig.subnetIds[1].Ref],
2025
2048
  };
2026
2049
  }
2027
2050
 
2028
- // Add VPC endpoints for AWS service optimization (optional but recommended)
2051
+ // Add VPC endpoints for AWS service optimization
2052
+ // ALWAYS create these to ensure Lambda functions have optimized access to AWS services
2029
2053
  if (AppDefinition.vpc.enableVPCEndpoints !== false) {
2030
2054
  definition.resources.Resources.VPCEndpointS3 = {
2031
2055
  Type: 'AWS::EC2::VPCEndpoint',
@@ -2034,7 +2058,7 @@ const composeServerlessDefinition = async (AppDefinition) => {
2034
2058
  ServiceName:
2035
2059
  'com.amazonaws.${self:provider.region}.s3',
2036
2060
  VpcEndpointType: 'Gateway',
2037
- RouteTableIds: [{ Ref: 'FriggLambdaRouteTable' }],
2061
+ RouteTableIds: [routeTableId],
2038
2062
  },
2039
2063
  };
2040
2064
 
@@ -2045,15 +2069,15 @@ const composeServerlessDefinition = async (AppDefinition) => {
2045
2069
  ServiceName:
2046
2070
  'com.amazonaws.${self:provider.region}.dynamodb',
2047
2071
  VpcEndpointType: 'Gateway',
2048
- RouteTableIds: [{ Ref: 'FriggLambdaRouteTable' }],
2072
+ RouteTableIds: [routeTableId],
2049
2073
  },
2050
2074
  };
2075
+ }
2051
2076
 
2052
- // Add KMS VPC endpoint if using KMS encryption
2053
- if (
2054
- AppDefinition.encryption?.fieldLevelEncryptionMethod ===
2055
- 'kms'
2056
- ) {
2077
+ // Add KMS VPC endpoint if using KMS encryption
2078
+ if (
2079
+ AppDefinition.encryption?.fieldLevelEncryptionMethod === 'kms'
2080
+ ) {
2057
2081
  // Validate we have VPC CIDR for security group configuration
2058
2082
  if (!discoveredResources.vpcCidr) {
2059
2083
  console.warn(
@@ -2181,7 +2205,6 @@ const composeServerlessDefinition = async (AppDefinition) => {
2181
2205
  }
2182
2206
  }
2183
2207
  }
2184
- }
2185
2208
 
2186
2209
  // SSM Parameter Store Configuration based on App Definition
2187
2210
  if (AppDefinition.ssm?.enable === true) {
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.db65660.0",
4
+ "version": "2.0.0--canary.428.2b9210c.1",
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.db65660.0",
13
- "@friggframework/test": "2.0.0--canary.428.db65660.0",
12
+ "@friggframework/schemas": "2.0.0--canary.428.2b9210c.1",
13
+ "@friggframework/test": "2.0.0--canary.428.2b9210c.1",
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.db65660.0",
36
- "@friggframework/prettier-config": "2.0.0--canary.428.db65660.0",
35
+ "@friggframework/eslint-config": "2.0.0--canary.428.2b9210c.1",
36
+ "@friggframework/prettier-config": "2.0.0--canary.428.2b9210c.1",
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": "db656605e3c91ad9e4e4fc6357c74397caaeed05"
71
+ "gitHead": "2b9210c7401ddd6baacac247aff11e3f73fcb315"
72
72
  }