@go-to-k/cdkd 0.102.3 → 0.102.5

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.
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-CuHRHcyW.js";
3
- import { A as resolveApp, B as CdkdError, C as AssetPublisher, D as Synthesizer, E as buildDockerImage, F as warnDeprecatedNoPrefixCliFlag, G as PartialFailureError, I as AssemblyReader, J as ResourceUpdateNotSupportedError, K as ProvisioningError, M as resolveSkipPrefix, N as resolveStateBucketWithDefault, O as getDefaultStateBucketName, P as resolveStateBucketWithDefaultAndSource, R as resolveBucketRegion, S as shouldRetainResource, T as WorkGraph, U as LocalInvokeBuildError, X as StackHasActiveImportsError, Y as RouteDiscoveryError, Z as StackTerminationProtectionError, _ as DiffCalculator, a as withRetry, at as getLogger, b as LockManager, c as collectInlinePolicyNamesManagedBySiblings, ct as getLiveRenderer, d as normalizeAwsTagsToCfn, dt as generateResourceName, f as resolveExplicitPhysicalId, ft as generateResourceNameWithFallback, g as IntrinsicFunctionResolver, h as assertRegionMatch, i as withResourceDeadline, j as resolveCaptureObservedState, k as getLegacyStateBucketName, l as CDK_PATH_TAG, lt as PATTERN_B_NAME_PROPERTIES, m as CloudControlProvider, mt as withStackName, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as normalizeAwsError, o as IMPLICIT_DELETE_DEPENDENCIES, p as ProviderRegistry, pt as withSkipPrefix, q as ResourceTimeoutError, r as DeployEngine, rt as withErrorHandling, s as IAMRoleProvider, st as runStackBuffered, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as matchesCdkPath, ut as PATTERN_B_RESOURCE_TYPES, v as DagBuilder, w as stringifyValue, x as S3StateBackend, y as TemplateParser } from "./deploy-engine-D4t--jpp.js";
3
+ import { A as resolveApp, B as CdkdError, C as AssetPublisher, D as Synthesizer, E as buildDockerImage, F as warnDeprecatedNoPrefixCliFlag, G as PartialFailureError, I as AssemblyReader, J as ResourceUpdateNotSupportedError, K as ProvisioningError, M as resolveSkipPrefix, N as resolveStateBucketWithDefault, O as getDefaultStateBucketName, P as resolveStateBucketWithDefaultAndSource, R as resolveBucketRegion, S as shouldRetainResource, T as WorkGraph, U as LocalInvokeBuildError, X as StackHasActiveImportsError, Y as RouteDiscoveryError, Z as StackTerminationProtectionError, _ as DiffCalculator, a as withRetry, at as getLogger, b as LockManager, c as collectInlinePolicyNamesManagedBySiblings, ct as getLiveRenderer, d as normalizeAwsTagsToCfn, dt as generateResourceName, f as resolveExplicitPhysicalId, ft as generateResourceNameWithFallback, g as IntrinsicFunctionResolver, h as assertRegionMatch, i as withResourceDeadline, j as resolveCaptureObservedState, k as getLegacyStateBucketName, l as CDK_PATH_TAG, lt as PATTERN_B_NAME_PROPERTIES, m as CloudControlProvider, mt as withStackName, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as normalizeAwsError, o as IMPLICIT_DELETE_DEPENDENCIES, p as ProviderRegistry, pt as withSkipPrefix, q as ResourceTimeoutError, r as DeployEngine, rt as withErrorHandling, s as IAMRoleProvider, st as runStackBuffered, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as matchesCdkPath, ut as PATTERN_B_RESOURCE_TYPES, v as DagBuilder, w as stringifyValue, x as S3StateBackend, y as TemplateParser } from "./deploy-engine-DGKtcKF6.js";
4
4
  import { createHash, createPublicKey, createVerify, randomBytes, randomUUID } from "node:crypto";
5
5
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListBucketsCommand, ListDirectoryBucketsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
6
6
  import { AddRoleToInstanceProfileCommand, AddUserToGroupCommand, AttachGroupPolicyCommand, AttachUserPolicyCommand, CreateGroupCommand, CreateInstanceProfileCommand, CreateLoginProfileCommand, CreateUserCommand, DeleteAccessKeyCommand, DeleteGroupCommand, DeleteGroupPolicyCommand, DeleteInstanceProfileCommand, DeleteLoginProfileCommand, DeleteRolePolicyCommand, DeleteUserCommand, DeleteUserPermissionsBoundaryCommand, DeleteUserPolicyCommand, DetachGroupPolicyCommand, DetachUserPolicyCommand, GetGroupCommand, GetGroupPolicyCommand, GetInstanceProfileCommand, GetRolePolicyCommand, GetUserCommand, GetUserPolicyCommand, IAMClient, ListAccessKeysCommand, ListAttachedGroupPoliciesCommand, ListAttachedUserPoliciesCommand, ListGroupPoliciesCommand, ListGroupsForUserCommand, ListInstanceProfilesCommand, ListUserPoliciesCommand, ListUserTagsCommand, ListUsersCommand, NoSuchEntityException, PutGroupPolicyCommand, PutRolePolicyCommand, PutUserPermissionsBoundaryCommand, PutUserPolicyCommand, RemoveRoleFromInstanceProfileCommand, RemoveUserFromGroupCommand, TagUserCommand, UntagUserCommand, UpdateLoginProfileCommand } from "@aws-sdk/client-iam";
@@ -1592,12 +1592,32 @@ var IAMInstanceProfileProvider = class {
1592
1592
  Path: path
1593
1593
  }));
1594
1594
  this.logger.debug(`Created IAM instance profile: ${instanceProfileName}`);
1595
- if (roles && Array.isArray(roles)) for (const roleName of roles) {
1596
- await this.iamClient.send(new AddRoleToInstanceProfileCommand({
1597
- InstanceProfileName: instanceProfileName,
1598
- RoleName: roleName
1599
- }));
1600
- this.logger.debug(`Added role ${roleName} to instance profile ${instanceProfileName}`);
1595
+ const attachedRoles = [];
1596
+ try {
1597
+ if (roles && Array.isArray(roles)) for (const roleName of roles) {
1598
+ await this.iamClient.send(new AddRoleToInstanceProfileCommand({
1599
+ InstanceProfileName: instanceProfileName,
1600
+ RoleName: roleName
1601
+ }));
1602
+ attachedRoles.push(roleName);
1603
+ this.logger.debug(`Added role ${roleName} to instance profile ${instanceProfileName}`);
1604
+ }
1605
+ } catch (innerError) {
1606
+ try {
1607
+ for (const roleName of attachedRoles) try {
1608
+ await this.iamClient.send(new RemoveRoleFromInstanceProfileCommand({
1609
+ InstanceProfileName: instanceProfileName,
1610
+ RoleName: roleName
1611
+ }));
1612
+ } catch (err) {
1613
+ if (!(err instanceof NoSuchEntityException)) throw err;
1614
+ }
1615
+ await this.iamClient.send(new DeleteInstanceProfileCommand({ InstanceProfileName: instanceProfileName }));
1616
+ this.logger.debug(`Cleaned up partially-created IAM instance profile ${logicalId} (${instanceProfileName}) after wiring failure`);
1617
+ } catch (cleanupError) {
1618
+ this.logger.warn(`Failed to clean up partially-created IAM instance profile ${logicalId} (${instanceProfileName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: remove every role (aws iam remove-role-from-instance-profile --instance-profile-name ${instanceProfileName} --role-name <name>) then aws iam delete-instance-profile --instance-profile-name ${instanceProfileName}`);
1619
+ }
1620
+ throw innerError;
1601
1621
  }
1602
1622
  this.logger.debug(`Successfully created IAM instance profile ${logicalId}: ${instanceProfileName}`);
1603
1623
  return {
@@ -1825,48 +1845,71 @@ var IAMUserGroupProvider = class {
1825
1845
  const tags = properties["Tags"];
1826
1846
  if (tags && Array.isArray(tags)) createParams.Tags = tags;
1827
1847
  const response = await this.iamClient.send(new CreateUserCommand(createParams));
1828
- const permissionsBoundary = properties["PermissionsBoundary"];
1829
- if (permissionsBoundary) {
1830
- await this.iamClient.send(new PutUserPermissionsBoundaryCommand({
1831
- UserName: userName,
1832
- PermissionsBoundary: permissionsBoundary
1833
- }));
1834
- this.logger.debug(`Set permissions boundary on user ${userName}`);
1835
- }
1836
- const loginProfile = properties["LoginProfile"];
1837
- if (loginProfile) {
1838
- await this.iamClient.send(new CreateLoginProfileCommand({
1839
- UserName: userName,
1840
- Password: loginProfile.Password,
1841
- PasswordResetRequired: loginProfile.PasswordResetRequired ?? false
1842
- }));
1843
- this.logger.debug(`Created login profile for user ${userName}`);
1844
- }
1845
- const managedPolicyArns = properties["ManagedPolicyArns"];
1846
- if (managedPolicyArns && Array.isArray(managedPolicyArns)) for (const policyArn of managedPolicyArns) {
1847
- await this.iamClient.send(new AttachUserPolicyCommand({
1848
- UserName: userName,
1849
- PolicyArn: policyArn
1850
- }));
1851
- this.logger.debug(`Attached managed policy ${policyArn} to user ${userName}`);
1852
- }
1853
- const userGroups = properties["Groups"];
1854
- if (userGroups && Array.isArray(userGroups)) for (const groupName of userGroups) {
1855
- await this.iamClient.send(new AddUserToGroupCommand({
1856
- UserName: userName,
1857
- GroupName: groupName
1858
- }));
1859
- this.logger.debug(`Added user ${userName} to group ${groupName}`);
1860
- }
1861
- const policies = properties["Policies"];
1862
- if (policies && Array.isArray(policies)) for (const policy of policies) {
1863
- const policyDoc = typeof policy.PolicyDocument === "string" ? policy.PolicyDocument : JSON.stringify(policy.PolicyDocument);
1864
- await this.iamClient.send(new PutUserPolicyCommand({
1865
- UserName: userName,
1866
- PolicyName: policy.PolicyName,
1867
- PolicyDocument: policyDoc
1868
- }));
1869
- this.logger.debug(`Added inline policy ${policy.PolicyName} to user ${userName}`);
1848
+ try {
1849
+ const permissionsBoundary = properties["PermissionsBoundary"];
1850
+ if (permissionsBoundary) {
1851
+ await this.iamClient.send(new PutUserPermissionsBoundaryCommand({
1852
+ UserName: userName,
1853
+ PermissionsBoundary: permissionsBoundary
1854
+ }));
1855
+ this.logger.debug(`Set permissions boundary on user ${userName}`);
1856
+ }
1857
+ const loginProfile = properties["LoginProfile"];
1858
+ if (loginProfile) {
1859
+ await this.iamClient.send(new CreateLoginProfileCommand({
1860
+ UserName: userName,
1861
+ Password: loginProfile.Password,
1862
+ PasswordResetRequired: loginProfile.PasswordResetRequired ?? false
1863
+ }));
1864
+ this.logger.debug(`Created login profile for user ${userName}`);
1865
+ }
1866
+ const managedPolicyArns = properties["ManagedPolicyArns"];
1867
+ if (managedPolicyArns && Array.isArray(managedPolicyArns)) for (const policyArn of managedPolicyArns) {
1868
+ await this.iamClient.send(new AttachUserPolicyCommand({
1869
+ UserName: userName,
1870
+ PolicyArn: policyArn
1871
+ }));
1872
+ this.logger.debug(`Attached managed policy ${policyArn} to user ${userName}`);
1873
+ }
1874
+ const userGroups = properties["Groups"];
1875
+ if (userGroups && Array.isArray(userGroups)) for (const groupName of userGroups) {
1876
+ await this.iamClient.send(new AddUserToGroupCommand({
1877
+ UserName: userName,
1878
+ GroupName: groupName
1879
+ }));
1880
+ this.logger.debug(`Added user ${userName} to group ${groupName}`);
1881
+ }
1882
+ const policies = properties["Policies"];
1883
+ if (policies && Array.isArray(policies)) for (const policy of policies) {
1884
+ const policyDoc = typeof policy.PolicyDocument === "string" ? policy.PolicyDocument : JSON.stringify(policy.PolicyDocument);
1885
+ await this.iamClient.send(new PutUserPolicyCommand({
1886
+ UserName: userName,
1887
+ PolicyName: policy.PolicyName,
1888
+ PolicyDocument: policyDoc
1889
+ }));
1890
+ this.logger.debug(`Added inline policy ${policy.PolicyName} to user ${userName}`);
1891
+ }
1892
+ } catch (innerError) {
1893
+ try {
1894
+ await this.removeUserFromAllGroups(userName);
1895
+ await this.detachAllUserPolicies(userName);
1896
+ await this.deleteAllUserInlinePolicies(userName);
1897
+ try {
1898
+ await this.iamClient.send(new DeleteLoginProfileCommand({ UserName: userName }));
1899
+ } catch (err) {
1900
+ if (!(err instanceof NoSuchEntityException)) throw err;
1901
+ }
1902
+ try {
1903
+ await this.iamClient.send(new DeleteUserPermissionsBoundaryCommand({ UserName: userName }));
1904
+ } catch (err) {
1905
+ if (!(err instanceof NoSuchEntityException)) throw err;
1906
+ }
1907
+ await this.iamClient.send(new DeleteUserCommand({ UserName: userName }));
1908
+ this.logger.debug(`Cleaned up partially-created IAM user ${logicalId} (${userName}) after wiring failure`);
1909
+ } catch (cleanupError) {
1910
+ this.logger.warn(`Failed to clean up partially-created IAM user ${logicalId} (${userName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: remove from groups, detach managed policies, delete inline policies, delete login profile (aws iam delete-login-profile --user-name ${userName}), remove permissions boundary (aws iam delete-user-permissions-boundary --user-name ${userName}), then aws iam delete-user --user-name ${userName}`);
1911
+ }
1912
+ throw innerError;
1870
1913
  }
1871
1914
  this.logger.debug(`Successfully created IAM user ${logicalId}: ${userName}`);
1872
1915
  return {
@@ -2135,23 +2178,35 @@ var IAMUserGroupProvider = class {
2135
2178
  const createParams = { GroupName: groupName };
2136
2179
  if (properties["Path"]) createParams.Path = properties["Path"];
2137
2180
  const response = await this.iamClient.send(new CreateGroupCommand(createParams));
2138
- const managedPolicyArns = properties["ManagedPolicyArns"];
2139
- if (managedPolicyArns && Array.isArray(managedPolicyArns)) for (const policyArn of managedPolicyArns) {
2140
- await this.iamClient.send(new AttachGroupPolicyCommand({
2141
- GroupName: groupName,
2142
- PolicyArn: policyArn
2143
- }));
2144
- this.logger.debug(`Attached managed policy ${policyArn} to group ${groupName}`);
2145
- }
2146
- const policies = properties["Policies"];
2147
- if (policies && Array.isArray(policies)) for (const policy of policies) {
2148
- const policyDoc = typeof policy.PolicyDocument === "string" ? policy.PolicyDocument : JSON.stringify(policy.PolicyDocument);
2149
- await this.iamClient.send(new PutGroupPolicyCommand({
2150
- GroupName: groupName,
2151
- PolicyName: policy.PolicyName,
2152
- PolicyDocument: policyDoc
2153
- }));
2154
- this.logger.debug(`Added inline policy ${policy.PolicyName} to group ${groupName}`);
2181
+ try {
2182
+ const managedPolicyArns = properties["ManagedPolicyArns"];
2183
+ if (managedPolicyArns && Array.isArray(managedPolicyArns)) for (const policyArn of managedPolicyArns) {
2184
+ await this.iamClient.send(new AttachGroupPolicyCommand({
2185
+ GroupName: groupName,
2186
+ PolicyArn: policyArn
2187
+ }));
2188
+ this.logger.debug(`Attached managed policy ${policyArn} to group ${groupName}`);
2189
+ }
2190
+ const policies = properties["Policies"];
2191
+ if (policies && Array.isArray(policies)) for (const policy of policies) {
2192
+ const policyDoc = typeof policy.PolicyDocument === "string" ? policy.PolicyDocument : JSON.stringify(policy.PolicyDocument);
2193
+ await this.iamClient.send(new PutGroupPolicyCommand({
2194
+ GroupName: groupName,
2195
+ PolicyName: policy.PolicyName,
2196
+ PolicyDocument: policyDoc
2197
+ }));
2198
+ this.logger.debug(`Added inline policy ${policy.PolicyName} to group ${groupName}`);
2199
+ }
2200
+ } catch (innerError) {
2201
+ try {
2202
+ await this.detachAllGroupPolicies(groupName);
2203
+ await this.deleteAllGroupInlinePolicies(groupName);
2204
+ await this.iamClient.send(new DeleteGroupCommand({ GroupName: groupName }));
2205
+ this.logger.debug(`Cleaned up partially-created IAM group ${logicalId} (${groupName}) after wiring failure`);
2206
+ } catch (cleanupError) {
2207
+ this.logger.warn(`Failed to clean up partially-created IAM group ${logicalId} (${groupName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: detach managed policies + delete inline policies, then aws iam delete-group --group-name ${groupName}`);
2208
+ }
2209
+ throw innerError;
2155
2210
  }
2156
2211
  this.logger.debug(`Successfully created IAM group ${logicalId}: ${groupName}`);
2157
2212
  return {
@@ -9789,27 +9844,37 @@ var EC2Provider = class {
9789
9844
  CidrBlock: cidrBlock,
9790
9845
  InstanceTenancy: properties["InstanceTenancy"] ?? void 0
9791
9846
  }))).Vpc.VpcId;
9792
- if (properties["EnableDnsHostnames"] === true || properties["EnableDnsHostnames"] === "true") await this.ec2Client.send(new ModifyVpcAttributeCommand({
9793
- VpcId: vpcId,
9794
- EnableDnsHostnames: { Value: true }
9795
- }));
9796
- if (properties["EnableDnsSupport"] === false || properties["EnableDnsSupport"] === "false") await this.ec2Client.send(new ModifyVpcAttributeCommand({
9797
- VpcId: vpcId,
9798
- EnableDnsSupport: { Value: false }
9799
- }));
9800
- await this.applyTags(vpcId, properties, logicalId);
9801
- await this.ec2Client.send(new DescribeVpcsCommand({ VpcIds: [vpcId] }));
9802
9847
  let defaultSgId = "";
9803
9848
  try {
9804
- defaultSgId = (await this.ec2Client.send(new DescribeSecurityGroupsCommand({ Filters: [{
9805
- Name: "vpc-id",
9806
- Values: [vpcId]
9807
- }, {
9808
- Name: "group-name",
9809
- Values: ["default"]
9810
- }] }))).SecurityGroups?.[0]?.GroupId || "";
9811
- } catch {
9812
- this.logger.debug(`Failed to get default SG for VPC ${vpcId}`);
9849
+ if (properties["EnableDnsHostnames"] === true || properties["EnableDnsHostnames"] === "true") await this.ec2Client.send(new ModifyVpcAttributeCommand({
9850
+ VpcId: vpcId,
9851
+ EnableDnsHostnames: { Value: true }
9852
+ }));
9853
+ if (properties["EnableDnsSupport"] === false || properties["EnableDnsSupport"] === "false") await this.ec2Client.send(new ModifyVpcAttributeCommand({
9854
+ VpcId: vpcId,
9855
+ EnableDnsSupport: { Value: false }
9856
+ }));
9857
+ await this.applyTags(vpcId, properties, logicalId);
9858
+ await this.ec2Client.send(new DescribeVpcsCommand({ VpcIds: [vpcId] }));
9859
+ try {
9860
+ defaultSgId = (await this.ec2Client.send(new DescribeSecurityGroupsCommand({ Filters: [{
9861
+ Name: "vpc-id",
9862
+ Values: [vpcId]
9863
+ }, {
9864
+ Name: "group-name",
9865
+ Values: ["default"]
9866
+ }] }))).SecurityGroups?.[0]?.GroupId || "";
9867
+ } catch {
9868
+ this.logger.debug(`Failed to get default SG for VPC ${vpcId}`);
9869
+ }
9870
+ } catch (innerError) {
9871
+ try {
9872
+ await this.ec2Client.send(new DeleteVpcCommand({ VpcId: vpcId }));
9873
+ this.logger.debug(`Cleaned up partially-created VPC ${logicalId} (${vpcId}) after wiring failure`);
9874
+ } catch (cleanupError) {
9875
+ this.logger.warn(`Failed to clean up partially-created VPC ${logicalId} (${vpcId}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws ec2 delete-vpc --vpc-id ${vpcId}`);
9876
+ }
9877
+ throw innerError;
9813
9878
  }
9814
9879
  this.logger.debug(`Successfully created VPC ${logicalId}: ${vpcId}`);
9815
9880
  return {
@@ -9940,12 +10005,22 @@ var EC2Provider = class {
9940
10005
  }));
9941
10006
  const subnetId = response.Subnet.SubnetId;
9942
10007
  const availabilityZone = response.Subnet.AvailabilityZone;
9943
- await this.applyTags(subnetId, properties, logicalId);
9944
- const mapPublicIp = properties["MapPublicIpOnLaunch"];
9945
- if (mapPublicIp === true || mapPublicIp === "true") await this.ec2Client.send(new ModifySubnetAttributeCommand({
9946
- SubnetId: subnetId,
9947
- MapPublicIpOnLaunch: { Value: true }
9948
- }));
10008
+ try {
10009
+ await this.applyTags(subnetId, properties, logicalId);
10010
+ const mapPublicIp = properties["MapPublicIpOnLaunch"];
10011
+ if (mapPublicIp === true || mapPublicIp === "true") await this.ec2Client.send(new ModifySubnetAttributeCommand({
10012
+ SubnetId: subnetId,
10013
+ MapPublicIpOnLaunch: { Value: true }
10014
+ }));
10015
+ } catch (innerError) {
10016
+ try {
10017
+ await this.ec2Client.send(new DeleteSubnetCommand({ SubnetId: subnetId }));
10018
+ this.logger.debug(`Cleaned up partially-created Subnet ${logicalId} (${subnetId}) after wiring failure`);
10019
+ } catch (cleanupError) {
10020
+ this.logger.warn(`Failed to clean up partially-created Subnet ${logicalId} (${subnetId}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws ec2 delete-subnet --subnet-id ${subnetId}`);
10021
+ }
10022
+ throw innerError;
10023
+ }
9949
10024
  this.logger.debug(`Successfully created Subnet ${logicalId}: ${subnetId}`);
9950
10025
  return {
9951
10026
  physicalId: subnetId,
@@ -10324,29 +10399,39 @@ var EC2Provider = class {
10324
10399
  Description: groupDescription,
10325
10400
  VpcId: properties["VpcId"] ?? void 0
10326
10401
  }))).GroupId;
10327
- await this.applyTags(groupId, properties, logicalId);
10328
- const ingressRules = properties["SecurityGroupIngress"];
10329
- if (ingressRules && Array.isArray(ingressRules)) for (const rule of ingressRules) await this.ec2Client.send(new AuthorizeSecurityGroupIngressCommand({
10330
- GroupId: groupId,
10331
- IpPermissions: [this.buildIpPermission(rule)]
10332
- }));
10333
- const egressRules = properties["SecurityGroupEgress"];
10334
- if (egressRules && Array.isArray(egressRules)) {
10335
- try {
10336
- await this.ec2Client.send(new RevokeSecurityGroupEgressCommand({
10402
+ try {
10403
+ await this.applyTags(groupId, properties, logicalId);
10404
+ const ingressRules = properties["SecurityGroupIngress"];
10405
+ if (ingressRules && Array.isArray(ingressRules)) for (const rule of ingressRules) await this.ec2Client.send(new AuthorizeSecurityGroupIngressCommand({
10406
+ GroupId: groupId,
10407
+ IpPermissions: [this.buildIpPermission(rule)]
10408
+ }));
10409
+ const egressRules = properties["SecurityGroupEgress"];
10410
+ if (egressRules && Array.isArray(egressRules)) {
10411
+ try {
10412
+ await this.ec2Client.send(new RevokeSecurityGroupEgressCommand({
10413
+ GroupId: groupId,
10414
+ IpPermissions: [{
10415
+ IpProtocol: "-1",
10416
+ IpRanges: [{ CidrIp: "0.0.0.0/0" }]
10417
+ }]
10418
+ }));
10419
+ } catch (error) {
10420
+ if (!this.isNotFoundError(error)) throw error;
10421
+ }
10422
+ for (const rule of egressRules) await this.ec2Client.send(new AuthorizeSecurityGroupEgressCommand({
10337
10423
  GroupId: groupId,
10338
- IpPermissions: [{
10339
- IpProtocol: "-1",
10340
- IpRanges: [{ CidrIp: "0.0.0.0/0" }]
10341
- }]
10424
+ IpPermissions: [this.buildIpPermission(rule, "egress")]
10342
10425
  }));
10343
- } catch (error) {
10344
- if (!this.isNotFoundError(error)) throw error;
10345
10426
  }
10346
- for (const rule of egressRules) await this.ec2Client.send(new AuthorizeSecurityGroupEgressCommand({
10347
- GroupId: groupId,
10348
- IpPermissions: [this.buildIpPermission(rule, "egress")]
10349
- }));
10427
+ } catch (innerError) {
10428
+ try {
10429
+ await this.ec2Client.send(new DeleteSecurityGroupCommand({ GroupId: groupId }));
10430
+ this.logger.debug(`Cleaned up partially-created SecurityGroup ${logicalId} (${groupId}) after wiring failure`);
10431
+ } catch (cleanupError) {
10432
+ this.logger.warn(`Failed to clean up partially-created SecurityGroup ${logicalId} (${groupId}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws ec2 delete-security-group --group-id ${groupId}`);
10433
+ }
10434
+ throw innerError;
10350
10435
  }
10351
10436
  this.logger.debug(`Successfully created SecurityGroup ${logicalId}: ${groupId}`);
10352
10437
  return {
@@ -10551,26 +10636,36 @@ var EC2Provider = class {
10551
10636
  }))).Instances?.[0];
10552
10637
  if (!instance?.InstanceId) throw new Error("No instance ID returned from RunInstances");
10553
10638
  const instanceId = instance.InstanceId;
10554
- await this.applyTags(instanceId, properties, logicalId);
10555
- this.logger.debug(`Waiting for instance ${instanceId} to be running...`);
10556
- await waitUntilInstanceRunning({
10557
- client: this.ec2Client,
10558
- maxWaitTime: 300
10559
- }, { InstanceIds: [instanceId] });
10560
- const runningInstance = (await this.ec2Client.send(new DescribeInstancesCommand({ InstanceIds: [instanceId] }))).Reservations?.[0]?.Instances?.[0];
10561
- const attributes = {
10562
- InstanceId: instanceId,
10563
- PrivateIp: runningInstance?.PrivateIpAddress ?? "",
10564
- PublicIp: runningInstance?.PublicIpAddress ?? "",
10565
- PrivateDnsName: runningInstance?.PrivateDnsName ?? "",
10566
- PublicDnsName: runningInstance?.PublicDnsName ?? "",
10567
- AvailabilityZone: runningInstance?.Placement?.AvailabilityZone ?? ""
10568
- };
10569
- this.logger.debug(`Successfully created EC2 Instance ${logicalId}: ${instanceId}`);
10570
- return {
10571
- physicalId: instanceId,
10572
- attributes
10573
- };
10639
+ try {
10640
+ await this.applyTags(instanceId, properties, logicalId);
10641
+ this.logger.debug(`Waiting for instance ${instanceId} to be running...`);
10642
+ await waitUntilInstanceRunning({
10643
+ client: this.ec2Client,
10644
+ maxWaitTime: 300
10645
+ }, { InstanceIds: [instanceId] });
10646
+ const runningInstance = (await this.ec2Client.send(new DescribeInstancesCommand({ InstanceIds: [instanceId] }))).Reservations?.[0]?.Instances?.[0];
10647
+ const attributes = {
10648
+ InstanceId: instanceId,
10649
+ PrivateIp: runningInstance?.PrivateIpAddress ?? "",
10650
+ PublicIp: runningInstance?.PublicIpAddress ?? "",
10651
+ PrivateDnsName: runningInstance?.PrivateDnsName ?? "",
10652
+ PublicDnsName: runningInstance?.PublicDnsName ?? "",
10653
+ AvailabilityZone: runningInstance?.Placement?.AvailabilityZone ?? ""
10654
+ };
10655
+ this.logger.debug(`Successfully created EC2 Instance ${logicalId}: ${instanceId}`);
10656
+ return {
10657
+ physicalId: instanceId,
10658
+ attributes
10659
+ };
10660
+ } catch (innerError) {
10661
+ try {
10662
+ await this.ec2Client.send(new TerminateInstancesCommand({ InstanceIds: [instanceId] }));
10663
+ this.logger.debug(`Terminate requested for partially-created EC2 Instance ${logicalId} (${instanceId}) after wiring failure (not waiting for terminated state)`);
10664
+ } catch (cleanupError) {
10665
+ this.logger.warn(`Failed to terminate partially-created EC2 Instance ${logicalId} (${instanceId}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. THE INSTANCE IS STILL RUNNING AND BILLING. Manual termination required: aws ec2 terminate-instances --instance-ids ${instanceId}`);
10666
+ }
10667
+ throw innerError;
10668
+ }
10574
10669
  } catch (error) {
10575
10670
  if (error instanceof ProvisioningError) throw error;
10576
10671
  const cause = error instanceof Error ? error : void 0;
@@ -42770,7 +42865,7 @@ function reorderArgs(argv) {
42770
42865
  */
42771
42866
  async function main() {
42772
42867
  const program = new Command();
42773
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.102.3");
42868
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.102.5");
42774
42869
  program.addCommand(createBootstrapCommand());
42775
42870
  program.addCommand(createSynthCommand());
42776
42871
  program.addCommand(createListCommand());