@continuous-excellence/ze-great-dashboard-aws 0.5.0 → 0.6.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/README.md +12 -6
- package/bootstrap/core-v1.yml +1 -0
- package/bootstrap/github-oidc-v2.yml +27 -1
- package/dist/bootstrap-check.d.ts +45 -0
- package/dist/bootstrap.d.ts +29 -0
- package/dist/cli.js +448 -37
- package/dist/guided.d.ts +1 -1
- package/dist/handoff.d.ts +2 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +401 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,10 +74,16 @@ npm exec -- ze-great-dashboard-aws doctor \
|
|
|
74
74
|
--region us-east-1
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
After assuming the generated GitHub deploy role, run the canonical blocking consistency check before
|
|
78
|
+
packaging or deployment:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
npm exec -- ze-great-dashboard-aws bootstrap check \
|
|
82
|
+
--config dashboard-bootstrap.json --format text
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Add `--resource-drift` only for a slower scheduled or manually dispatched CloudFormation drift
|
|
86
|
+
audit. Neither form updates stack resources.
|
|
81
87
|
|
|
82
88
|
Package the release. This validates the board and writes `lambda.zip`, `release.json`, and
|
|
83
89
|
`template.yml` to the output directory:
|
|
@@ -127,7 +133,7 @@ does not grant public Lambda invoke permission.
|
|
|
127
133
|
To upgrade, install a newer exact package version and repeat package, upload, and deploy. A change to
|
|
128
134
|
`board.yaml` follows the same path; it does not require a package change.
|
|
129
135
|
|
|
130
|
-
After upgrading, also check the [bootstrap
|
|
136
|
+
After upgrading, also check the [bootstrap consistency guidance](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-bootstrap.md#check-bootstrap-consistency-on-every-deployment).
|
|
131
137
|
Compatible releases may add optional bootstrap capabilities without changing the contract version.
|
|
132
138
|
If your workflow verifies a consumer-owned gateway stack, add `githubOidc.consumerGatewayStackName`
|
|
133
139
|
to the reviewed manifest and update the GitHub OIDC stack; other consumers do not need to rerun
|
|
@@ -144,7 +150,7 @@ for the supported secret reference and integration boundary.
|
|
|
144
150
|
| `doctor` | Read-only preflight for an existing parameter file. |
|
|
145
151
|
| `parameters` | Generate or update application CloudFormation parameters. |
|
|
146
152
|
| `package` | Validate board YAML and build a deployable Lambda release. |
|
|
147
|
-
| `bootstrap` |
|
|
153
|
+
| `bootstrap` | Plan and guide administrator bootstrap work; `bootstrap check` is the explicit live diagnostic used by CI. |
|
|
148
154
|
| `publish-assets` | Provider-only: publish immutable client assets. Normal consumers use the hosted client. |
|
|
149
155
|
| `deploy` | Provider-only: automation helper for a provider-managed asset and Lambda deployment. |
|
|
150
156
|
|
package/bootstrap/core-v1.yml
CHANGED
|
@@ -105,6 +105,7 @@ Resources:
|
|
|
105
105
|
|
|
106
106
|
Outputs:
|
|
107
107
|
BootstrapContractVersion: { Value: '1' }
|
|
108
|
+
BootstrapTemplateRevision: { Value: '1.1' }
|
|
108
109
|
ArtifactBucketName: { Value: !Ref ArtifactBucket }
|
|
109
110
|
ArtifactBucketArn: { Value: !GetAtt ArtifactBucket.Arn }
|
|
110
111
|
CloudFormationExecutionRoleArn: { Value: !GetAtt CloudFormationExecutionRole.Arn }
|
|
@@ -7,6 +7,7 @@ Parameters:
|
|
|
7
7
|
GitHubOwnerId: { Type: String, Description: Immutable numeric GitHub owner id }
|
|
8
8
|
GitHubRepositoryId: { Type: String, Description: Immutable numeric GitHub repository id }
|
|
9
9
|
GitHubEnvironment: { Type: String, Description: Protected GitHub Environment name }
|
|
10
|
+
CoreBootstrapStackName: { Type: String }
|
|
10
11
|
ApplicationStackName: { Type: String }
|
|
11
12
|
ConsumerGatewayStackName:
|
|
12
13
|
Type: String
|
|
@@ -56,6 +57,31 @@ Resources:
|
|
|
56
57
|
Effect: Allow
|
|
57
58
|
Action: [cloudformation:CreateChangeSet, cloudformation:DescribeChangeSet, cloudformation:ExecuteChangeSet, cloudformation:DeleteChangeSet, cloudformation:DescribeStacks, cloudformation:DescribeStackEvents, cloudformation:GetTemplate, cloudformation:GetTemplateSummary]
|
|
58
59
|
Resource: !Sub 'arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${ApplicationStackName}/*'
|
|
60
|
+
- Sid: InspectBootstrapStacks
|
|
61
|
+
Effect: Allow
|
|
62
|
+
Action: [cloudformation:DescribeStacks, cloudformation:DetectStackDrift, cloudformation:DescribeStackResourceDrifts]
|
|
63
|
+
Resource:
|
|
64
|
+
- !Sub 'arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${CoreBootstrapStackName}/*'
|
|
65
|
+
- !Sub 'arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AWS::StackName}/*'
|
|
66
|
+
# Detection-status requests are keyed by an opaque detection id, so AWS does not
|
|
67
|
+
# support scoping this one read action to a stack ARN.
|
|
68
|
+
- Sid: ReadBootstrapDriftDetectionStatus
|
|
69
|
+
Effect: Allow
|
|
70
|
+
Action: cloudformation:DescribeStackDriftDetectionStatus
|
|
71
|
+
Resource: '*'
|
|
72
|
+
# CloudFormation uses the caller's read permissions when these administrator-created
|
|
73
|
+
# stacks have no service role. Keep resource inspection on the exact bootstrap bucket
|
|
74
|
+
# and roles whose properties drift detection evaluates.
|
|
75
|
+
- Sid: InspectBootstrapBucketConfiguration
|
|
76
|
+
Effect: Allow
|
|
77
|
+
Action: [s3:GetBucketAcl, s3:GetBucketPolicy, s3:GetBucketPublicAccessBlock, s3:GetEncryptionConfiguration, s3:GetBucketOwnershipControls, s3:GetBucketTagging]
|
|
78
|
+
Resource: !Sub 'arn:${AWS::Partition}:s3:::${ArtifactBucketName}'
|
|
79
|
+
- Sid: InspectBootstrapRoleConfiguration
|
|
80
|
+
Effect: Allow
|
|
81
|
+
Action: [iam:GetRole, iam:GetRolePolicy, iam:ListRolePolicies, iam:ListAttachedRolePolicies, iam:ListRoleTags]
|
|
82
|
+
Resource:
|
|
83
|
+
- !Ref CloudFormationExecutionRoleArn
|
|
84
|
+
- !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${ApplicationStackName}-github-deploy'
|
|
59
85
|
- !If
|
|
60
86
|
- HasConsumerGatewayStack
|
|
61
87
|
- Sid: ReadConsumerGatewayStack
|
|
@@ -71,5 +97,5 @@ Resources:
|
|
|
71
97
|
|
|
72
98
|
Outputs:
|
|
73
99
|
BootstrapContractVersion: { Value: '2' }
|
|
74
|
-
BootstrapTemplateRevision: { Value: '2.
|
|
100
|
+
BootstrapTemplateRevision: { Value: '2.2' }
|
|
75
101
|
GitHubDeployRoleArn: { Value: !GetAtt GitHubDeployRole.Arn }
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type BootstrapConfig, type BootstrapConsistency, type BootstrapKind } from './bootstrap.js';
|
|
2
|
+
export type BootstrapResourceDifference = {
|
|
3
|
+
path?: string;
|
|
4
|
+
differenceType?: string;
|
|
5
|
+
expectedValue?: string;
|
|
6
|
+
actualValue?: string;
|
|
7
|
+
};
|
|
8
|
+
export type BootstrapResourceDrift = {
|
|
9
|
+
logicalId: string;
|
|
10
|
+
resourceType?: string;
|
|
11
|
+
status?: string;
|
|
12
|
+
differences: BootstrapResourceDifference[];
|
|
13
|
+
};
|
|
14
|
+
export type BootstrapResourceDriftResult = {
|
|
15
|
+
ok: boolean;
|
|
16
|
+
status: string;
|
|
17
|
+
detectionId?: string;
|
|
18
|
+
reason?: string;
|
|
19
|
+
resources: BootstrapResourceDrift[];
|
|
20
|
+
};
|
|
21
|
+
export type BootstrapStackCheck = {
|
|
22
|
+
kind: BootstrapKind;
|
|
23
|
+
stackName: string;
|
|
24
|
+
stackStatus?: string;
|
|
25
|
+
contractVersion: string;
|
|
26
|
+
templateRevision?: string;
|
|
27
|
+
templateSha256: string;
|
|
28
|
+
consistency: BootstrapConsistency;
|
|
29
|
+
resourceDrift?: BootstrapResourceDriftResult;
|
|
30
|
+
};
|
|
31
|
+
export type BootstrapCheck = {
|
|
32
|
+
ok: boolean;
|
|
33
|
+
packageVersion: string;
|
|
34
|
+
stacks: BootstrapStackCheck[];
|
|
35
|
+
};
|
|
36
|
+
export type BootstrapCheckDependencies = {
|
|
37
|
+
execute(command: string, args: string[]): Promise<string>;
|
|
38
|
+
sleep?(milliseconds: number): Promise<void>;
|
|
39
|
+
now?(): number;
|
|
40
|
+
};
|
|
41
|
+
export declare function formatBootstrapCheckText(result: BootstrapCheck): string;
|
|
42
|
+
/** Runs the explicitly named live bootstrap diagnostic; it never changes stack resources. */
|
|
43
|
+
export declare function checkBootstrap(config: BootstrapConfig, options: {
|
|
44
|
+
resourceDrift?: boolean;
|
|
45
|
+
}, dependencies: BootstrapCheckDependencies): Promise<BootstrapCheck>;
|
package/dist/bootstrap.d.ts
CHANGED
|
@@ -5,6 +5,9 @@ export type CloudFormationParameterValue = {
|
|
|
5
5
|
UsePreviousValue?: boolean;
|
|
6
6
|
};
|
|
7
7
|
export type DeployedBootstrapStack = {
|
|
8
|
+
StackName?: string;
|
|
9
|
+
StackId?: string;
|
|
10
|
+
StackStatus?: string;
|
|
8
11
|
Parameters?: CloudFormationParameterValue[];
|
|
9
12
|
Outputs?: {
|
|
10
13
|
OutputKey: string;
|
|
@@ -31,10 +34,36 @@ export type BootstrapConfig = {
|
|
|
31
34
|
consumerGatewayStackName?: string;
|
|
32
35
|
};
|
|
33
36
|
};
|
|
37
|
+
export type BootstrapTemplateInspection = {
|
|
38
|
+
kind: BootstrapKind;
|
|
39
|
+
path: string;
|
|
40
|
+
contractVersion: string;
|
|
41
|
+
templateRevision?: string;
|
|
42
|
+
sha256: string;
|
|
43
|
+
resources: {
|
|
44
|
+
logicalId: string;
|
|
45
|
+
type: string;
|
|
46
|
+
}[];
|
|
47
|
+
iamActions: string[];
|
|
48
|
+
};
|
|
49
|
+
export type BootstrapPlan = {
|
|
50
|
+
packageVersion: string;
|
|
51
|
+
packageTemplates: BootstrapTemplateInspection[];
|
|
52
|
+
configuration: BootstrapConfig;
|
|
53
|
+
notes: string[];
|
|
54
|
+
};
|
|
55
|
+
export type BootstrapConsistency = {
|
|
56
|
+
ok: boolean;
|
|
57
|
+
mismatches: string[];
|
|
58
|
+
};
|
|
34
59
|
export declare function bootstrapTemplatePath(kind: BootstrapKind): Promise<string>;
|
|
35
60
|
export declare function bootstrapTemplate(kind: BootstrapKind): Promise<string>;
|
|
36
61
|
export declare function bootstrapContractVersion(template: string): string;
|
|
37
62
|
export declare function bootstrapTemplateRevision(template: string): string;
|
|
63
|
+
/** Returns installed templates and a reviewable, non-secret plan without external calls. */
|
|
64
|
+
export declare function bootstrapPlan(config: BootstrapConfig): Promise<BootstrapPlan>;
|
|
65
|
+
/** Compares describe-stacks data with manifest and installed-template values without network access. */
|
|
66
|
+
export declare function bootstrapConsistency(kind: BootstrapKind, config: BootstrapConfig, stackInput: unknown, expectedContract: string, expectedRevision?: string, coreOutputs?: Record<string, string | undefined>): BootstrapConsistency;
|
|
38
67
|
/** Merges a new parameter set with deployed values without silently dropping configuration. */
|
|
39
68
|
export declare function mergeBootstrapParameters(requested: CloudFormationParameterValue[], deployed: CloudFormationParameterValue[]): CloudFormationParameterValue[];
|
|
40
69
|
/** Validates a caller-captured `describe-stacks` result before an upgrade merges it locally. */
|