import type { ChangeSetSummary, Stack } from '@aws-sdk/client-cloudformation'; import { Diagnosis } from './diagnosis'; import type { SDK } from '../aws-auth/sdk'; import type { EnvironmentResources } from '../environment'; import type { IoHelper } from '../io/private/io-helper'; import type { ISourceTracer } from '../source-tracing/private/source-tracing'; import type { ResourceErrors } from '../stack-events/resource-errors'; export interface CloudFormationStackDiagnoserProps { readonly sdk: SDK; readonly envResources?: EnvironmentResources; readonly sourceTracer: ISourceTracer; readonly ioHelper: IoHelper; readonly topLevelStackHierarchicalId: string; /** * Optionally: a function to return an SDK that can be used for additional * (readonly) exploratory calls. * * Typically, this should be an SDK that is primed with the "lookup" role, or similar. * * This is necessary because the "deploy" role will not typically have permissions to * do very much. * * Regardless, if lookups of additional information fail, they are emitted at debug * level and their information is simply not added to the output. */ readonly additionalExplorationSdkProvider?: SdkProvider; /** * Whether to fetch the failure details of hooks that failed resources, via the * `GetHookResult` API, and attach them to the diagnosis. * * During a deployment the activity stream already shows these details live, so * `cdk deploy` leaves this off to avoid repeating them. `cdk diagnose` has no * live stream and enables it. * * @default false */ readonly fetchHookFailureDetails?: boolean; } export type SdkProvider = () => Promise; /** * Diagnose a stack's failed state * * - First, determine the stack's state. * - If it is in a failed state, we started a deployment that failed. Describe the stack * events, and try to determine the root cause from that. * - If it is in a normal state, see if there are any failed change sets. Either * get the failure message from the change set, or get the failure events from * the change set (early validation). * * This class works at the CloudFormation level, and does not deal with tracing * CloudFormation errors to construct code sources yet. */ /** * Options that affect how a diagnosis is performed. */ export interface DiagnoseOptions { /** * Whether CloudFormation rollback is enabled for this deployment. * * When rollback is enabled, failed resources are torn down before we can * inspect their runtime state (e.g. ECS tasks), so the investigation degrades * to durable sources and may suggest re-running with `--no-rollback`. * * @default true */ readonly rollbackEnabled?: boolean; } export interface DiagnoseChangeSetOptions { /** * Report a change set that cannot be executed as a problem. * * By default only a change set that failed to create is a problem: one that contains no changes, * or that has since been deleted, is reported as healthy because for `deploy` those are normal * outcomes. Set this when you are about to execute the change set, so that anything other than * `CREATE_COMPLETE` is reported as a problem instead. * * @default false */ readonly requireExecutable?: boolean; } export declare class CloudFormationStackDiagnoser { private readonly props; private readonly cfn; private parentStackLogicalIds; private _additionalExplorationSdkPromise?; private rollbackEnabled; constructor(props: CloudFormationStackDiagnoserProps); /** * Diagnose a stack's root cause given no pre-existing state */ diagnoseFromFresh(stackName: string): Promise; /** * Diagnose potential problems with the change set */ diagnoseChangeSet(changeSet: ChangeSetSummary, options?: DiagnoseChangeSetOptions): Promise; /** * Diagnose potential problems with the change set */ diagnoseFromErrorCollection(errors: ResourceErrors, stack: Stack, allowFallback?: boolean, options?: DiagnoseOptions): Promise; /** * Run the stack-level CloudTrail investigation and attach its findings to the problems. * * One sweep per diagnosis (cdk diagnose or cdk deploy): the sweep covers the whole failure * window and correlates events to resources afterwards. A finding whose resource is itself * among the problems (matched by stack AND logical ID — logical IDs repeat across nested * stacks) is attached to that problem. Findings for other resources, and notes about the * scan itself, are labeled with the resource they belong to and reported at the stack * level. When run right after a deployment, the events may not be delivered yet, in which * case the output notifies the user. */ private addCloudTrailContext; /** * Diagnose a deployment failure via stack events * * This is the same logic that the deployment monitor uses. */ private _diagnoseViaStackEvents; private _diagnoseChangeSetFailureFromStackName; /** * Try to diagnose the reason that caused a changeset to fail to create * * There are a couple of different reasons this can happen, and we go through each of them in order. * * Usually this starts from trying to detect an error message pattern in the change set status reason, * and then potentially going to fetch additional information using additional API calls. */ private _diagnoseChangeSetFailure; private _diagnoseChangeSetProblems; /** * Try to read the resource-specific reasons for a changeset failure from `DescribeEvents`. * * If we couldn't read the events or there are 0 errors returned by that API, check whether * the change set was failed by CloudFormation Hooks and report those. Otherwise, return a * generic error. */ private _reportChangeSetFailureFromEvents; /** * Find the hooks that failed this change set, and return their failure details as resource errors. * * Failures of hooks with failure mode WARN don't fail a change set, so those are excluded. * Returns an empty array if hook results can't be listed (e.g. for lack of permissions). */ private _changeSetHookErrors; /** * Get the failure details for a hook result summary. * * Tries `GetHookResult` first, which includes annotations (Guard Hooks). Falls back * to the summary itself, whose `HookStatusReason` carries the details for other hooks. */ private _hookResultDetails; private enhanceErrors; private enhanceError; /** * Fetch the failure details of the hooks that caused the given resource error. * * The resource's own status reason only names the hooks that failed it (e.g. * "The following hook(s) failed: [X]"); the actual failure details live in the * hook results API. Falls back to the hook event's status reason if the fetch * fails or returns no details. * * Only active when `fetchHookFailureDetails` is set (i.e. for `cdk diagnose`); * during a deployment the activity stream already shows these details. */ private hookFailureContext; private investigateResourceBestEffort; /** * Build a generic stack error from the given change set information * * We can't point to a specific resource. */ private _nonSpecificChangeSetError; /** * Look for nested change sets that have failed, and diagnose those. */ private _diagnoseNestedChangeSetFailure; private _findFailedNestedStack; /** * Try to parse failed auto-imports out from a change set status * * The pattern looks like this: * * ``` * CloudFormation is attempting to import some resources because they already exist in your account. The resources must have the DeletionPolicy attribute set to 'Retain' or 'RetainExceptOnCreate' in the template for successful import. The affected resources are SomeBucketD5B70704 ({BucketName=zomaareenbucket}) * ``` * * Followed by * * ``` * LogicalID ({Prop=Value,Prop=Value}), LogicalID ({Prop=Value}), ... * ``` */ private _tryDetectFailedAutoImport; /** * Return the additional exploration SDK, if available. */ private additionalExplorationSdk; } /** * Return true if the given change set has no changes * * This must be determined from the status, not the 'Changes' array on the * object; the latter can be empty because no resources were changed, but if * there are changes to Outputs, the change set can still be executed. */ export declare function changeSetHasNoChanges(description: ChangeSetSummary): boolean; //# sourceMappingURL=stack-diagnoser.d.ts.map