@go-to-k/cdkd 0.102.2 → 0.102.4

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 {
@@ -3435,15 +3490,27 @@ var S3BucketProvider = class {
3435
3490
  const region = await this.getRegion();
3436
3491
  if (region !== "us-east-1") createParams.CreateBucketConfiguration = { LocationConstraint: region };
3437
3492
  if (properties["ObjectLockEnabled"] === true || properties["ObjectLockEnabled"] === "true") createParams.ObjectLockEnabledForBucket = true;
3493
+ let createdNewBucket = false;
3438
3494
  try {
3439
3495
  await this.s3Client.send(new CreateBucketCommand(createParams));
3496
+ createdNewBucket = true;
3440
3497
  this.logger.debug(`Created S3 bucket: ${bucketName}`);
3441
3498
  } catch (createError) {
3442
3499
  if (createError instanceof Error && (createError.name === "BucketAlreadyOwnedByYou" || createError.message.includes("you already own it"))) this.logger.debug(`S3 bucket ${bucketName} already exists and is owned by you`);
3443
3500
  else throw createError;
3444
3501
  }
3445
- await this.applyConfiguration(bucketName, properties);
3446
- await this.applyAllSubConfigsForCreate(bucketName, properties);
3502
+ try {
3503
+ await this.applyConfiguration(bucketName, properties);
3504
+ await this.applyAllSubConfigsForCreate(bucketName, properties);
3505
+ } catch (innerError) {
3506
+ if (createdNewBucket) try {
3507
+ await this.s3Client.send(new DeleteBucketCommand({ Bucket: bucketName }));
3508
+ this.logger.debug(`Cleaned up partially-created S3 bucket ${logicalId} (${bucketName}) after wiring failure`);
3509
+ } catch (cleanupError) {
3510
+ this.logger.warn(`Failed to clean up partially-created S3 bucket ${logicalId} (${bucketName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws s3api delete-bucket --bucket '${bucketName}'`);
3511
+ }
3512
+ throw innerError;
3513
+ }
3447
3514
  const attributes = await this.buildAttributes(bucketName);
3448
3515
  this.logger.debug(`Successfully created S3 bucket ${logicalId}: ${bucketName}`);
3449
3516
  return {
@@ -7810,46 +7877,56 @@ var LogsLogGroupProvider = class {
7810
7877
  const cfnTags = properties["Tags"];
7811
7878
  createParams.tags = Object.fromEntries(cfnTags.map((t) => [t.Key, t.Value]));
7812
7879
  }
7813
- await this.logsClient.send(new CreateLogGroupCommand(createParams));
7814
- const retentionInDays = properties["RetentionInDays"];
7815
- if (retentionInDays) await this.logsClient.send(new PutRetentionPolicyCommand({
7816
- logGroupName,
7817
- retentionInDays
7818
- }));
7819
- if (properties["DataProtectionPolicy"]) {
7820
- const policyDocument = typeof properties["DataProtectionPolicy"] === "string" ? properties["DataProtectionPolicy"] : JSON.stringify(properties["DataProtectionPolicy"]);
7821
- await this.logsClient.send(new PutDataProtectionPolicyCommand({
7822
- logGroupIdentifier: logGroupName,
7823
- policyDocument
7824
- }));
7880
+ let createdNewLogGroup = false;
7881
+ try {
7882
+ await this.logsClient.send(new CreateLogGroupCommand(createParams));
7883
+ createdNewLogGroup = true;
7884
+ } catch (createError) {
7885
+ if (createError instanceof ResourceAlreadyExistsException) this.logger.debug(`Log group ${logGroupName} already exists, using existing`);
7886
+ else throw createError;
7825
7887
  }
7826
- const fieldIndexPolicies = properties["FieldIndexPolicies"];
7827
- if (fieldIndexPolicies && fieldIndexPolicies.length > 0) {
7828
- if (fieldIndexPolicies.length > 1) this.logger.debug(`Log group ${logicalId} declares ${fieldIndexPolicies.length} FieldIndexPolicies; AWS only supports one log-group-level field index policy. Applying the first.`);
7829
- const first = fieldIndexPolicies[0];
7830
- const policyDocument = typeof first === "string" ? first : JSON.stringify(first);
7831
- await this.logsClient.send(new PutIndexPolicyCommand({
7888
+ try {
7889
+ const retentionInDays = properties["RetentionInDays"];
7890
+ if (retentionInDays) await this.logsClient.send(new PutRetentionPolicyCommand({
7891
+ logGroupName,
7892
+ retentionInDays
7893
+ }));
7894
+ if (properties["DataProtectionPolicy"]) {
7895
+ const policyDocument = typeof properties["DataProtectionPolicy"] === "string" ? properties["DataProtectionPolicy"] : JSON.stringify(properties["DataProtectionPolicy"]);
7896
+ await this.logsClient.send(new PutDataProtectionPolicyCommand({
7897
+ logGroupIdentifier: logGroupName,
7898
+ policyDocument
7899
+ }));
7900
+ }
7901
+ const fieldIndexPolicies = properties["FieldIndexPolicies"];
7902
+ if (fieldIndexPolicies && fieldIndexPolicies.length > 0) {
7903
+ if (fieldIndexPolicies.length > 1) this.logger.debug(`Log group ${logicalId} declares ${fieldIndexPolicies.length} FieldIndexPolicies; AWS only supports one log-group-level field index policy. Applying the first.`);
7904
+ const first = fieldIndexPolicies[0];
7905
+ const policyDocument = typeof first === "string" ? first : JSON.stringify(first);
7906
+ await this.logsClient.send(new PutIndexPolicyCommand({
7907
+ logGroupIdentifier: logGroupName,
7908
+ policyDocument
7909
+ }));
7910
+ }
7911
+ if (properties["BearerTokenAuthenticationEnabled"] !== void 0) await this.logsClient.send(new PutBearerTokenAuthenticationCommand({
7832
7912
  logGroupIdentifier: logGroupName,
7833
- policyDocument
7913
+ bearerTokenAuthenticationEnabled: properties["BearerTokenAuthenticationEnabled"]
7834
7914
  }));
7915
+ } catch (innerError) {
7916
+ if (createdNewLogGroup) try {
7917
+ await this.logsClient.send(new DeleteLogGroupCommand({ logGroupName }));
7918
+ this.logger.debug(`Cleaned up partially-created log group ${logicalId} (${logGroupName}) after wiring failure`);
7919
+ } catch (cleanupError) {
7920
+ this.logger.warn(`Failed to clean up partially-created log group ${logicalId} (${logGroupName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws logs delete-log-group --log-group-name '${logGroupName}'`);
7921
+ }
7922
+ throw innerError;
7835
7923
  }
7836
- if (properties["BearerTokenAuthenticationEnabled"] !== void 0) await this.logsClient.send(new PutBearerTokenAuthenticationCommand({
7837
- logGroupIdentifier: logGroupName,
7838
- bearerTokenAuthenticationEnabled: properties["BearerTokenAuthenticationEnabled"]
7839
- }));
7840
7924
  this.logger.debug(`Successfully created log group ${logicalId}: ${logGroupName}`);
7841
7925
  return {
7842
7926
  physicalId: logGroupName,
7843
7927
  attributes: { Arn: await this.buildArn(logGroupName) }
7844
7928
  };
7845
7929
  } catch (error) {
7846
- if (error instanceof ResourceAlreadyExistsException) {
7847
- this.logger.debug(`Log group ${logGroupName} already exists, using existing`);
7848
- return {
7849
- physicalId: logGroupName,
7850
- attributes: { Arn: await this.buildArn(logGroupName) }
7851
- };
7852
- }
7853
7930
  const cause = error instanceof Error ? error : void 0;
7854
7931
  throw new ProvisioningError(`Failed to create log group ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, logGroupName, cause);
7855
7932
  }
@@ -8756,16 +8833,26 @@ var SSMParameterProvider = class {
8756
8833
  if (properties["Policies"]) putParams.Policies = properties["Policies"];
8757
8834
  if (properties["DataType"]) putParams.DataType = properties["DataType"];
8758
8835
  await this.ssmClient.send(new PutParameterCommand(putParams));
8759
- if (properties["Tags"]) {
8760
- const ssmTags = properties["Tags"].map((t) => ({
8761
- Key: t.Key,
8762
- Value: t.Value
8763
- }));
8764
- await this.ssmClient.send(new AddTagsToResourceCommand({
8765
- ResourceType: "Parameter",
8766
- ResourceId: name,
8767
- Tags: ssmTags
8768
- }));
8836
+ try {
8837
+ if (properties["Tags"]) {
8838
+ const ssmTags = properties["Tags"].map((t) => ({
8839
+ Key: t.Key,
8840
+ Value: t.Value
8841
+ }));
8842
+ await this.ssmClient.send(new AddTagsToResourceCommand({
8843
+ ResourceType: "Parameter",
8844
+ ResourceId: name,
8845
+ Tags: ssmTags
8846
+ }));
8847
+ }
8848
+ } catch (innerError) {
8849
+ try {
8850
+ await this.ssmClient.send(new DeleteParameterCommand({ Name: name }));
8851
+ this.logger.debug(`Cleaned up partially-created SSM parameter ${logicalId} (${name}) after wiring failure`);
8852
+ } catch (cleanupError) {
8853
+ this.logger.warn(`Failed to clean up partially-created SSM parameter ${logicalId} (${name}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws ssm delete-parameter --name '${name}'`);
8854
+ }
8855
+ throw innerError;
8769
8856
  }
8770
8857
  this.logger.debug(`Successfully created SSM parameter ${logicalId}: ${name}`);
8771
8858
  return {
@@ -42738,7 +42825,7 @@ function reorderArgs(argv) {
42738
42825
  */
42739
42826
  async function main() {
42740
42827
  const program = new Command();
42741
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.102.2");
42828
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.102.4");
42742
42829
  program.addCommand(createBootstrapCommand());
42743
42830
  program.addCommand(createSynthCommand());
42744
42831
  program.addCommand(createListCommand());