@go-to-k/cdkd 0.217.0 → 0.218.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.
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-DWUnLza1.js";
3
- import { $ as CFN_TEMPLATE_URL_LIMIT, A as DagBuilder, B as getDockerCmd, C as CloudControlProvider, D as IntrinsicFunctionResolver, Dt as withErrorHandling, E as isTerminationProtectionPropagationError, Et as normalizeAwsError, F as AssetPublisher, Ft as generateResourceName, G as getLegacyStateBucketName, H as runDockerStreaming, I as stringifyValue, It as generateResourceNameWithFallback, J as resolveSkipPrefix, K as resolveApp, L as WorkGraph, Lt as withSkipPrefix, M as LockManager, Mt as getLiveRenderer, N as S3StateBackend, Nt as PATTERN_B_NAME_PROPERTIES, O as applyRoleArnIfSet, P as shouldRetainResource, Pt as PATTERN_B_RESOURCE_TYPES, Q as CFN_TEMPLATE_BODY_LIMIT, R as buildDockerImage, Rt as withStackName, S as findActionableSilentDrops, T as disableInstanceApiTermination, U as Synthesizer, V as runDockerForeground, W as getDefaultStateBucketName, X as resolveStateBucketWithDefaultAndSource, Y as resolveStateBucketWithDefault, Z as warnDeprecatedNoPrefixCliFlag, _ as CDK_PATH_TAG, _t as ProvisioningError, a as withRetry, at as resolveBucketRegion, b as resolveExplicitPhysicalId, bt as StackHasActiveImportsError, c as formatResourceLine, d as gray, dt as LocalMigrateError, et as MIGRATE_TMP_PREFIX, f as green, ft as LocalStartServiceError, g as collectInlinePolicyNamesManagedBySiblings, gt as PartialFailureError, h as IAMRoleProvider, ht as NestedStackChildDirectDestroyError, i as withResourceDeadline, j as TemplateParser, jt as runStackBuffered, k as DiffCalculator, kt as getLogger, l as bold, m as yellow, mt as MissingCdkCliError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as uploadCfnTemplate, o as isRetryableTransientError, p as red, q as resolveCaptureObservedState, r as DeployEngine, rt as AssemblyReader, s as IMPLICIT_DELETE_DEPENDENCIES, st as CdkdError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as findLargeInlineResources, u as cyan, ut as LocalInvokeBuildError$1, v as matchesCdkPath, vt as ResourceTimeoutError, w as assertRegionMatch, x as ProviderRegistry, xt as StackTerminationProtectionError, y as normalizeAwsTagsToCfn, yt as ResourceUpdateNotSupportedError, z as formatDockerLoginError } from "./deploy-engine-UctzfQ8M.js";
3
+ import { $ as CFN_TEMPLATE_URL_LIMIT, A as DagBuilder, B as getDockerCmd, C as CloudControlProvider, D as IntrinsicFunctionResolver, Dt as withErrorHandling, E as isTerminationProtectionPropagationError, Et as normalizeAwsError, F as AssetPublisher, Ft as generateResourceName, G as getLegacyStateBucketName, H as runDockerStreaming, I as stringifyValue, It as generateResourceNameWithFallback, J as resolveSkipPrefix, K as resolveApp, L as WorkGraph, Lt as withSkipPrefix, M as LockManager, Mt as getLiveRenderer, N as S3StateBackend, Nt as PATTERN_B_NAME_PROPERTIES, O as applyRoleArnIfSet, P as shouldRetainResource, Pt as PATTERN_B_RESOURCE_TYPES, Q as CFN_TEMPLATE_BODY_LIMIT, R as buildDockerImage, Rt as withStackName, S as findActionableSilentDrops, T as disableInstanceApiTermination, U as Synthesizer, V as runDockerForeground, W as getDefaultStateBucketName, X as resolveStateBucketWithDefaultAndSource, Y as resolveStateBucketWithDefault, Z as warnDeprecatedNoPrefixCliFlag, _ as CDK_PATH_TAG, _t as ProvisioningError, a as withRetry, at as resolveBucketRegion, b as resolveExplicitPhysicalId, bt as StackHasActiveImportsError, c as formatResourceLine, d as gray, dt as LocalMigrateError, et as MIGRATE_TMP_PREFIX, f as green, ft as LocalStartServiceError, g as collectInlinePolicyNamesManagedBySiblings, gt as PartialFailureError, h as IAMRoleProvider, ht as NestedStackChildDirectDestroyError, i as withResourceDeadline, j as TemplateParser, jt as runStackBuffered, k as DiffCalculator, kt as getLogger, l as bold, m as yellow, mt as MissingCdkCliError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as uploadCfnTemplate, o as isRetryableTransientError, p as red, q as resolveCaptureObservedState, r as DeployEngine, rt as AssemblyReader, s as IMPLICIT_DELETE_DEPENDENCIES, st as CdkdError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as findLargeInlineResources, u as cyan, ut as LocalInvokeBuildError$1, v as matchesCdkPath, vt as ResourceTimeoutError, w as assertRegionMatch, x as ProviderRegistry, xt as StackTerminationProtectionError, y as normalizeAwsTagsToCfn, yt as ResourceUpdateNotSupportedError, z as formatDockerLoginError } from "./deploy-engine-DXr1irt9.js";
4
4
  import { AsyncLocalStorage } from "node:async_hooks";
5
5
  import { randomBytes, randomUUID } from "node:crypto";
6
6
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, 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";
@@ -9,7 +9,7 @@ import { CreateQueueCommand, DeleteQueueCommand, GetQueueAttributesCommand, GetQ
9
9
  import { CreateTopicCommand, DeleteTopicCommand, GetSubscriptionAttributesCommand, GetTopicAttributesCommand, ListTagsForResourceCommand, ListTopicsCommand, NotFoundException, SNSClient, SetTopicAttributesCommand, SubscribeCommand, TagResourceCommand, UnsubscribeCommand, UntagResourceCommand } from "@aws-sdk/client-sns";
10
10
  import { AddPermissionCommand, CreateEventSourceMappingCommand, CreateFunctionCommand, CreateFunctionUrlConfigCommand, DeleteEventSourceMappingCommand, DeleteFunctionCommand, DeleteFunctionConcurrencyCommand, DeleteFunctionUrlConfigCommand, DeleteLayerVersionCommand, GetEventSourceMappingCommand, GetFunctionCommand, GetFunctionConcurrencyCommand, GetFunctionRecursionConfigCommand, GetFunctionUrlConfigCommand, GetLayerVersionByArnCommand, GetPolicyCommand as GetPolicyCommand$1, LambdaClient, ListFunctionsCommand, ListLayersCommand, ListTagsCommand, PublishLayerVersionCommand, PutFunctionConcurrencyCommand, PutFunctionRecursionConfigCommand, RemovePermissionCommand, ResourceNotFoundException, TagResourceCommand as TagResourceCommand$1, UntagResourceCommand as UntagResourceCommand$1, UpdateEventSourceMappingCommand, UpdateFunctionCodeCommand, UpdateFunctionConfigurationCommand, UpdateFunctionUrlConfigCommand, waitUntilFunctionUpdatedV2 } from "@aws-sdk/client-lambda";
11
11
  import { AssumeRoleCommand, GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
12
- import { AssociateRouteTableCommand, AttachInternetGatewayCommand, AuthorizeSecurityGroupEgressCommand, AuthorizeSecurityGroupIngressCommand, CreateInternetGatewayCommand, CreateNatGatewayCommand, CreateNetworkAclCommand, CreateNetworkAclEntryCommand, CreateRouteCommand, CreateRouteTableCommand, CreateSecurityGroupCommand, CreateSubnetCommand, CreateTagsCommand, CreateVpcCommand, DeleteInternetGatewayCommand, DeleteNatGatewayCommand, DeleteNetworkAclCommand, DeleteNetworkAclEntryCommand, DeleteNetworkInterfaceCommand, DeleteRouteCommand, DeleteRouteTableCommand, DeleteSecurityGroupCommand, DeleteSubnetCommand, DeleteTagsCommand, DeleteVpcCommand, DescribeAvailabilityZonesCommand, DescribeInstanceAttributeCommand, DescribeInstancesCommand, DescribeInternetGatewaysCommand, DescribeNatGatewaysCommand, DescribeNetworkAclsCommand, DescribeNetworkInterfacesCommand, DescribeRouteTablesCommand, DescribeSecurityGroupsCommand, DescribeSubnetsCommand, DescribeVolumesCommand, DescribeVpcAttributeCommand, DescribeVpcsCommand, DetachInternetGatewayCommand, DisassociateRouteTableCommand, EC2Client, ModifySubnetAttributeCommand, ModifyVpcAttributeCommand, ReplaceNetworkAclAssociationCommand, RevokeSecurityGroupEgressCommand, RevokeSecurityGroupIngressCommand, RunInstancesCommand, TerminateInstancesCommand, waitUntilInstanceRunning, waitUntilInstanceTerminated, waitUntilNatGatewayAvailable, waitUntilNatGatewayDeleted } from "@aws-sdk/client-ec2";
12
+ import { AssociateRouteTableCommand, AttachInternetGatewayCommand, AuthorizeSecurityGroupEgressCommand, AuthorizeSecurityGroupIngressCommand, CreateInternetGatewayCommand, CreateNatGatewayCommand, CreateNetworkAclCommand, CreateNetworkAclEntryCommand, CreateRouteCommand, CreateRouteTableCommand, CreateSecurityGroupCommand, CreateSubnetCommand, CreateTagsCommand, CreateVpcCommand, DeleteInternetGatewayCommand, DeleteNatGatewayCommand, DeleteNetworkAclCommand, DeleteNetworkAclEntryCommand, DeleteNetworkInterfaceCommand, DeleteRouteCommand, DeleteRouteTableCommand, DeleteSecurityGroupCommand, DeleteSubnetCommand, DeleteTagsCommand, DeleteVpcCommand, DescribeAvailabilityZonesCommand, DescribeInstanceAttributeCommand, DescribeInstanceCreditSpecificationsCommand, DescribeInstancesCommand, DescribeInternetGatewaysCommand, DescribeNatGatewaysCommand, DescribeNetworkAclsCommand, DescribeNetworkInterfacesCommand, DescribeRouteTablesCommand, DescribeSecurityGroupsCommand, DescribeSubnetsCommand, DescribeVolumesCommand, DescribeVpcAttributeCommand, DescribeVpcsCommand, DetachInternetGatewayCommand, DisassociateRouteTableCommand, EC2Client, ModifyInstanceAttributeCommand, ModifyInstanceCreditSpecificationCommand, ModifyInstanceMetadataOptionsCommand, ModifySubnetAttributeCommand, ModifyVpcAttributeCommand, MonitorInstancesCommand, ReplaceNetworkAclAssociationCommand, RevokeSecurityGroupEgressCommand, RevokeSecurityGroupIngressCommand, RunInstancesCommand, TerminateInstancesCommand, UnmonitorInstancesCommand, waitUntilInstanceRunning, waitUntilInstanceTerminated, waitUntilNatGatewayAvailable, waitUntilNatGatewayDeleted } from "@aws-sdk/client-ec2";
13
13
  import { CreateTableCommand, DeleteResourcePolicyCommand, DeleteTableCommand, DescribeContinuousBackupsCommand, DescribeContributorInsightsCommand, DescribeKinesisStreamingDestinationCommand, DescribeTableCommand, DescribeTimeToLiveCommand, DisableKinesisStreamingDestinationCommand, DynamoDBClient, EnableKinesisStreamingDestinationCommand, GetResourcePolicyCommand, ListTablesCommand, ListTagsOfResourceCommand, PutResourcePolicyCommand, ResourceNotFoundException as ResourceNotFoundException$1, TagResourceCommand as TagResourceCommand$2, UntagResourceCommand as UntagResourceCommand$2, UpdateContinuousBackupsCommand, UpdateContributorInsightsCommand, UpdateTableCommand, UpdateTimeToLiveCommand } from "@aws-sdk/client-dynamodb";
14
14
  import { CloudFormationClient, CreateChangeSetCommand, DeleteChangeSetCommand, DeleteStackCommand, DescribeChangeSetCommand, DescribeStackEventsCommand, DescribeStackResourcesCommand, DescribeStacksCommand, DescribeTypeCommand, ExecuteChangeSetCommand, GetTemplateCommand, UpdateStackCommand, waitUntilChangeSetCreateComplete, waitUntilStackDeleteComplete, waitUntilStackImportComplete, waitUntilStackUpdateComplete } from "@aws-sdk/client-cloudformation";
15
15
  import { APIGatewayClient, CreateAuthorizerCommand, CreateDeploymentCommand, CreateResourceCommand, CreateStageCommand, DeleteAuthorizerCommand, DeleteDeploymentCommand, DeleteMethodCommand, DeleteResourceCommand, DeleteStageCommand, GetAccountCommand, GetAuthorizerCommand, GetDeploymentCommand, GetMethodCommand, GetResourceCommand, GetStageCommand, NotFoundException as NotFoundException$1, PutIntegrationCommand, PutIntegrationResponseCommand, PutMethodCommand, PutMethodResponseCommand, TagResourceCommand as TagResourceCommand$3, UntagResourceCommand as UntagResourceCommand$3, UpdateAccountCommand, UpdateAuthorizerCommand, UpdateMethodCommand, UpdateStageCommand } from "@aws-sdk/client-api-gateway";
@@ -13035,7 +13035,12 @@ var EC2Provider = class {
13035
13035
  "IamInstanceProfile",
13036
13036
  "UserData",
13037
13037
  "BlockDeviceMappings",
13038
- "Tags"
13038
+ "Tags",
13039
+ "DisableApiTermination",
13040
+ "MetadataOptions",
13041
+ "Monitoring",
13042
+ "EbsOptimized",
13043
+ "CreditSpecification"
13039
13044
  ])],
13040
13045
  ["AWS::EC2::NetworkAcl", new Set(["VpcId", "Tags"])],
13041
13046
  ["AWS::EC2::NetworkAclEntry", new Set([
@@ -13925,7 +13930,12 @@ var EC2Provider = class {
13925
13930
  Arn: iamInstanceProfile["Arn"],
13926
13931
  Name: iamInstanceProfile["Name"]
13927
13932
  } : void 0,
13928
- BlockDeviceMappings: this.buildBlockDeviceMappings(properties)
13933
+ BlockDeviceMappings: this.buildBlockDeviceMappings(properties),
13934
+ DisableApiTermination: this.coerceBool(properties["DisableApiTermination"]),
13935
+ EbsOptimized: this.coerceBool(properties["EbsOptimized"]),
13936
+ Monitoring: this.buildRunInstancesMonitoring(properties),
13937
+ MetadataOptions: this.buildMetadataOptions(properties),
13938
+ CreditSpecification: this.buildCreditSpecification(properties)
13929
13939
  }))).Instances?.[0];
13930
13940
  if (!instance?.InstanceId) throw new Error("No instance ID returned from RunInstances");
13931
13941
  const instanceId = instance.InstanceId;
@@ -13969,6 +13979,7 @@ var EC2Provider = class {
13969
13979
  this.logger.debug(`Updating EC2 Instance ${logicalId}: ${physicalId}`);
13970
13980
  try {
13971
13981
  await this.applyTagDiff(physicalId, previousProperties["Tags"], properties["Tags"]);
13982
+ await this.updateInstanceSecurityProps(physicalId, properties, previousProperties);
13972
13983
  const instance = (await this.ec2Client.send(new DescribeInstancesCommand({ InstanceIds: [physicalId] }))).Reservations?.[0]?.Instances?.[0];
13973
13984
  return {
13974
13985
  physicalId,
@@ -13987,6 +13998,57 @@ var EC2Provider = class {
13987
13998
  throw new ProvisioningError(`Failed to update EC2 Instance ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
13988
13999
  }
13989
14000
  }
14001
+ /**
14002
+ * Apply in-place modifications for four of the five security-focused
14003
+ * backfill props (#609). Each is diffed against `previousProperties` so a
14004
+ * no-drift round-trip (`update(state, state)`) issues zero mutating calls
14005
+ * (the `cdkd drift --revert` invariant). Each maps to a distinct EC2
14006
+ * modify API:
14007
+ * - DisableApiTermination -> ModifyInstanceAttribute
14008
+ * - Monitoring -> MonitorInstances / UnmonitorInstances
14009
+ * - MetadataOptions -> ModifyInstanceMetadataOptions
14010
+ * - CreditSpecification -> ModifyInstanceCreditSpecification
14011
+ * EbsOptimized is NOT here: it can only be changed on a STOPPED instance, so
14012
+ * an EbsOptimized change is routed to replacement (see ReplacementRules).
14013
+ */
14014
+ async updateInstanceSecurityProps(physicalId, properties, previousProperties) {
14015
+ const newDisableApiTermination = this.coerceBool(properties["DisableApiTermination"]);
14016
+ const oldDisableApiTermination = this.coerceBool(previousProperties["DisableApiTermination"]);
14017
+ if (newDisableApiTermination !== void 0 && newDisableApiTermination !== oldDisableApiTermination) await this.ec2Client.send(new ModifyInstanceAttributeCommand({
14018
+ InstanceId: physicalId,
14019
+ DisableApiTermination: { Value: newDisableApiTermination }
14020
+ }));
14021
+ const newMonitoring = this.coerceBool(properties["Monitoring"]);
14022
+ const oldMonitoring = this.coerceBool(previousProperties["Monitoring"]);
14023
+ if (newMonitoring !== void 0 && newMonitoring !== oldMonitoring) if (newMonitoring) await this.ec2Client.send(new MonitorInstancesCommand({ InstanceIds: [physicalId] }));
14024
+ else await this.ec2Client.send(new UnmonitorInstancesCommand({ InstanceIds: [physicalId] }));
14025
+ const newMetadata = this.buildMetadataOptions(properties);
14026
+ const oldMetadata = this.buildMetadataOptions(previousProperties);
14027
+ if (newMetadata !== void 0 && !this.shallowEqual(newMetadata, oldMetadata)) await this.ec2Client.send(new ModifyInstanceMetadataOptionsCommand({
14028
+ InstanceId: physicalId,
14029
+ ...newMetadata
14030
+ }));
14031
+ const newCpuCredits = this.readCpuCredits(properties["CreditSpecification"]);
14032
+ const oldCpuCredits = this.readCpuCredits(previousProperties["CreditSpecification"]);
14033
+ if (newCpuCredits !== void 0 && newCpuCredits !== oldCpuCredits) await this.ec2Client.send(new ModifyInstanceCreditSpecificationCommand({ InstanceCreditSpecifications: [{
14034
+ InstanceId: physicalId,
14035
+ CpuCredits: newCpuCredits
14036
+ }] }));
14037
+ }
14038
+ /**
14039
+ * Shallow value-equality for the small flat MetadataOptions request shape.
14040
+ * Treats `undefined` and an absent object as equal so the no-drift
14041
+ * round-trip produces zero modify calls.
14042
+ */
14043
+ shallowEqual(a, b) {
14044
+ if (b === void 0) return false;
14045
+ const ra = a;
14046
+ const rb = b;
14047
+ const keysA = Object.keys(ra);
14048
+ const keysB = Object.keys(rb);
14049
+ if (keysA.length !== keysB.length) return false;
14050
+ return keysA.every((k) => ra[k] === rb[k]);
14051
+ }
13990
14052
  async deleteInstance(logicalId, physicalId, resourceType, context) {
13991
14053
  this.logger.debug(`Terminating EC2 Instance ${logicalId}: ${physicalId}`);
13992
14054
  const removeProtection = context?.removeProtection === true;
@@ -14046,6 +14108,73 @@ var EC2Provider = class {
14046
14108
  });
14047
14109
  }
14048
14110
  /**
14111
+ * Coerce a CFn boolean-ish value (`true` | `false` | `"true"` | `"false"`)
14112
+ * into a real boolean, or `undefined` when the property is absent. CFn
14113
+ * templates can carry either the JSON boolean or its string form depending
14114
+ * on how the value was produced (a literal vs an intrinsic-resolved value),
14115
+ * so the wire boundary must normalize both. Returns `undefined` for absent
14116
+ * props so the field is omitted from the SDK input (AWS keeps its default)
14117
+ * rather than being forced to `false`.
14118
+ */
14119
+ coerceBool(value) {
14120
+ if (value === void 0 || value === null) return void 0;
14121
+ if (typeof value === "boolean") return value;
14122
+ if (value === "true") return true;
14123
+ if (value === "false") return false;
14124
+ }
14125
+ /**
14126
+ * Build the RunInstances `Monitoring` shape from the CFn `Monitoring`
14127
+ * boolean. AWS expects `{ Enabled: boolean }`; CFn carries a flat boolean.
14128
+ * Returns `undefined` when the prop is absent so the field is omitted.
14129
+ */
14130
+ buildRunInstancesMonitoring(properties) {
14131
+ const enabled = this.coerceBool(properties["Monitoring"]);
14132
+ if (enabled === void 0) return void 0;
14133
+ return { Enabled: enabled };
14134
+ }
14135
+ /**
14136
+ * Build the RunInstances `MetadataOptions` shape from the CFn
14137
+ * `MetadataOptions` object. CFn and the SDK share field names
14138
+ * (HttpTokens / HttpEndpoint / HttpPutResponseHopLimit / HttpProtocolIpv6 /
14139
+ * InstanceMetadataTags). `HttpPutResponseHopLimit` is numeric — CFn may
14140
+ * carry it as a string, so coerce at the wire boundary. Only emits keys the
14141
+ * template actually set so AWS keeps its defaults for the rest.
14142
+ */
14143
+ buildMetadataOptions(properties) {
14144
+ const opts = properties["MetadataOptions"];
14145
+ if (!opts || typeof opts !== "object") return void 0;
14146
+ const result = {};
14147
+ if (opts["HttpTokens"] !== void 0) result.HttpTokens = opts["HttpTokens"];
14148
+ if (opts["HttpEndpoint"] !== void 0) result.HttpEndpoint = opts["HttpEndpoint"];
14149
+ if (opts["HttpProtocolIpv6"] !== void 0) result.HttpProtocolIpv6 = opts["HttpProtocolIpv6"];
14150
+ if (opts["InstanceMetadataTags"] !== void 0) result.InstanceMetadataTags = opts["InstanceMetadataTags"];
14151
+ const hopLimit = opts["HttpPutResponseHopLimit"];
14152
+ if (hopLimit !== void 0 && hopLimit !== null) result.HttpPutResponseHopLimit = Number(hopLimit);
14153
+ return Object.keys(result).length > 0 ? result : void 0;
14154
+ }
14155
+ /**
14156
+ * Build the RunInstances `CreditSpecification` shape from the CFn
14157
+ * `CreditSpecification` object. CFn uses `CPUCredits` (capital CPU, the
14158
+ * canonical CDK `CfnInstance` emission); accept the SDK-style `CpuCredits`
14159
+ * too for hand-authored templates. Returns `undefined` when absent / empty.
14160
+ */
14161
+ buildCreditSpecification(properties) {
14162
+ const cpuCredits = this.readCpuCredits(properties["CreditSpecification"]);
14163
+ if (cpuCredits === void 0) return void 0;
14164
+ return { CpuCredits: cpuCredits };
14165
+ }
14166
+ /**
14167
+ * Extract the CpuCredits string from a CFn `CreditSpecification` object,
14168
+ * tolerating both the canonical `CPUCredits` key and the SDK-style
14169
+ * `CpuCredits` key. Shared by create() and update().
14170
+ */
14171
+ readCpuCredits(spec) {
14172
+ if (!spec || typeof spec !== "object") return void 0;
14173
+ const obj = spec;
14174
+ const raw = obj["CPUCredits"] ?? obj["CpuCredits"];
14175
+ return typeof raw === "string" ? raw : void 0;
14176
+ }
14177
+ /**
14049
14178
  * Build an IpPermission object from CloudFormation-style properties.
14050
14179
  *
14051
14180
  * The EC2 IpPermission shape is identical for ingress and egress; only the
@@ -14720,6 +14849,17 @@ var EC2Provider = class {
14720
14849
  if (instance.SourceDestCheck !== void 0) result["SourceDestCheck"] = instance.SourceDestCheck;
14721
14850
  const monitoringState = instance.Monitoring?.State;
14722
14851
  result["Monitoring"] = monitoringState === "enabled" || monitoringState === "pending";
14852
+ if (instance.EbsOptimized !== void 0) result["EbsOptimized"] = instance.EbsOptimized;
14853
+ const md = instance.MetadataOptions;
14854
+ if (md !== void 0) {
14855
+ const out = {};
14856
+ if (md.HttpTokens !== void 0) out["HttpTokens"] = md.HttpTokens;
14857
+ if (md.HttpPutResponseHopLimit !== void 0) out["HttpPutResponseHopLimit"] = md.HttpPutResponseHopLimit;
14858
+ if (md.HttpEndpoint !== void 0) out["HttpEndpoint"] = md.HttpEndpoint;
14859
+ if (md.HttpProtocolIpv6 !== void 0) out["HttpProtocolIpv6"] = md.HttpProtocolIpv6;
14860
+ if (md.InstanceMetadataTags !== void 0) out["InstanceMetadataTags"] = md.InstanceMetadataTags;
14861
+ if (Object.keys(out).length > 0) result["MetadataOptions"] = out;
14862
+ }
14723
14863
  if (instance.Placement?.Tenancy !== void 0) result["Tenancy"] = instance.Placement.Tenancy;
14724
14864
  if (instance.IamInstanceProfile?.Arn !== void 0) result["IamInstanceProfile"] = instance.IamInstanceProfile.Arn;
14725
14865
  const volumeIds = (instance.BlockDeviceMappings ?? []).filter((m) => m.Ebs?.VolumeId !== void 0).map((m) => m.Ebs.VolumeId);
@@ -14763,6 +14903,12 @@ var EC2Provider = class {
14763
14903
  } catch (err) {
14764
14904
  this.logger.debug(`DescribeInstanceAttribute(disableApiTermination, ${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
14765
14905
  }
14906
+ try {
14907
+ const cpuCredits = (await this.ec2Client.send(new DescribeInstanceCreditSpecificationsCommand({ InstanceIds: [physicalId] }))).InstanceCreditSpecifications?.[0]?.CpuCredits;
14908
+ if (cpuCredits !== void 0) result["CreditSpecification"] = { CPUCredits: cpuCredits };
14909
+ } catch (err) {
14910
+ this.logger.debug(`DescribeInstanceCreditSpecifications(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
14911
+ }
14766
14912
  return result;
14767
14913
  }
14768
14914
  async readNetworkAclCurrentState(physicalId) {
@@ -53328,7 +53474,7 @@ function reorderArgs(argv) {
53328
53474
  async function main() {
53329
53475
  installPipeCloseHandler();
53330
53476
  const program = new Command();
53331
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.217.0");
53477
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.218.0");
53332
53478
  program.addCommand(createBootstrapCommand());
53333
53479
  program.addCommand(createSynthCommand());
53334
53480
  program.addCommand(createListCommand());