@continuous-excellence/ze-great-dashboard-aws 0.5.1 → 0.6.1
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 +52 -129
- 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 +451 -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 +404 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,163 +1,86 @@
|
|
|
1
|
-
# Ze Great Dashboard AWS
|
|
1
|
+
# Ze Great Dashboard on AWS
|
|
2
2
|
|
|
3
|
-
`@continuous-excellence/ze-great-dashboard-aws` packages a
|
|
4
|
-
|
|
5
|
-
CloudFormation template.
|
|
3
|
+
`@continuous-excellence/ze-great-dashboard-aws` packages a board as a private AWS Lambda. It
|
|
4
|
+
includes the Lambda runtime, matching browser client, deployment CLI, and CloudFormation templates.
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
This deployment path is intended for teams that already operate AWS and have a protected gateway
|
|
7
|
+
such as API Gateway or an ALB. It deliberately does not create a public endpoint, choose an
|
|
8
|
+
authentication policy, or manage secret values.
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
invoke, or authenticate the gateway.
|
|
10
|
+
If you are evaluating the dashboard, start with the repository's
|
|
11
|
+
[local setup](https://github.com/robertfmurdock/ze-great-dashboard#run-it-locally). You do not need
|
|
12
|
+
AWS to try it.
|
|
15
13
|
|
|
16
|
-
##
|
|
14
|
+
## What you need
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
- Node.js 22 or newer, npm, the AWS CLI, and `jq`.
|
|
17
|
+
- An AWS administrator for the one-time bootstrap.
|
|
18
|
+
- A pre-existing central GitHub OIDC provider and a protected GitHub Environment if GitHub Actions
|
|
19
|
+
will deploy the dashboard.
|
|
20
|
+
- A consumer-owned gateway that can privately invoke Lambda and enforce your access policy.
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
The included deployment works out of the box with public GitHub repositories and HTTP endpoints
|
|
23
|
+
that do not require credentials. Private sources require a consumer-owned runtime integration; the
|
|
24
|
+
stock template does not turn a Secrets Manager reference into `token_env` variables.
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
## Deployment map
|
|
27
|
+
|
|
28
|
+
1. An administrator creates the artifact bucket and restricted deployment roles using the
|
|
29
|
+
[AWS bootstrap guide](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-bootstrap.md).
|
|
30
|
+
2. The application owner writes `board.yaml`, packages the Lambda, and deploys its private
|
|
31
|
+
CloudFormation stack using the
|
|
32
|
+
[deployment guide](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-setup.md).
|
|
33
|
+
3. The consumer connects the returned `ServerFunctionArn` to its protected gateway.
|
|
34
|
+
4. GitHub Actions can repeat the package-and-deploy step after the administrator configures the two
|
|
35
|
+
reviewed role ARNs.
|
|
36
|
+
|
|
37
|
+
## The normal application workflow
|
|
38
|
+
|
|
39
|
+
Pin an exact package version in the repository that owns the deployment:
|
|
26
40
|
|
|
27
41
|
```sh
|
|
28
|
-
npm install --save-exact @continuous-excellence/ze-great-dashboard-aws
|
|
42
|
+
npm install --save-exact @continuous-excellence/ze-great-dashboard-aws
|
|
29
43
|
```
|
|
30
44
|
|
|
31
|
-
|
|
32
|
-
see the [board configuration guide](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/board-configuration.md)
|
|
33
|
-
for the full schema.
|
|
34
|
-
|
|
35
|
-
```yaml
|
|
36
|
-
sources:
|
|
37
|
-
github:
|
|
38
|
-
type: github-actions
|
|
39
|
-
repo: your-org/your-repo
|
|
40
|
-
branch: main
|
|
41
|
-
token_env: GITHUB_TOKEN
|
|
42
|
-
|
|
43
|
-
boards:
|
|
44
|
-
operations:
|
|
45
|
-
refresh: 60s
|
|
46
|
-
panels:
|
|
47
|
-
- id: build
|
|
48
|
-
type: pipeline-status
|
|
49
|
-
source: github
|
|
50
|
-
pipeline: main.yml
|
|
51
|
-
position: { x: 0, y: 0, w: 8, h: 6 }
|
|
52
|
-
- id: version
|
|
53
|
-
type: http-value
|
|
54
|
-
url: https://status.example.com/version.json
|
|
55
|
-
json_path: $.version
|
|
56
|
-
position: { x: 8, y: 0, w: 4, h: 6 }
|
|
57
|
-
```
|
|
45
|
+
Append `@version` when installing a previously reviewed release rather than the current one.
|
|
58
46
|
|
|
59
|
-
|
|
60
|
-
bootstrap:
|
|
47
|
+
After bootstrap is complete, the recurring workflow is only:
|
|
61
48
|
|
|
62
49
|
```sh
|
|
63
50
|
npm exec -- ze-great-dashboard-aws parameters \
|
|
64
51
|
--bootstrap-config dashboard-bootstrap.json \
|
|
65
52
|
--output aws-dashboard-parameters.json
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
After the parameter file exists, run the read-only doctor. It checks local tooling, your AWS
|
|
69
|
-
identity, parameters, the artifact bucket and Region, and the matching hosted client:
|
|
70
53
|
|
|
71
|
-
```sh
|
|
72
54
|
npm exec -- ze-great-dashboard-aws doctor \
|
|
73
55
|
--parameters aws-dashboard-parameters.json \
|
|
74
56
|
--region us-east-1
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
If you retain a captured GitHub OIDC stack, add `--github-oidc-stack-json
|
|
78
|
-
github-oidc-deployed-stack.json` to have the doctor warn when the installed package contains a
|
|
79
|
-
newer bootstrap template revision. The warning is advisory and does not make the application
|
|
80
|
-
deployment perform bootstrap changes.
|
|
81
57
|
|
|
82
|
-
Package the release. This validates the board and writes `lambda.zip`, `release.json`, and
|
|
83
|
-
`template.yml` to the output directory:
|
|
84
|
-
|
|
85
|
-
```sh
|
|
86
58
|
npm exec -- ze-great-dashboard-aws package \
|
|
87
59
|
--board-config board.yaml \
|
|
88
60
|
--output aws-dashboard-release
|
|
89
61
|
```
|
|
90
62
|
|
|
91
|
-
|
|
63
|
+
The deployment guide covers the S3 upload, CloudFormation command, gateway handoff, and CI example.
|
|
64
|
+
Changing `board.yaml` or upgrading the pinned package uses this same path.
|
|
92
65
|
|
|
93
|
-
|
|
94
|
-
export AWS_REGION=us-east-1
|
|
95
|
-
export STACK_NAME=my-ze-great-dashboard
|
|
96
|
-
|
|
97
|
-
ARTIFACT_BUCKET="$(jq -er \
|
|
98
|
-
'.[] | select(.ParameterKey == "LambdaArtifactBucket") | .ParameterValue' \
|
|
99
|
-
aws-dashboard-parameters.json)"
|
|
100
|
-
ARTIFACT_KEY="$(jq -er '.artifactKey' aws-dashboard-release/release.json)"
|
|
66
|
+
## Package boundaries
|
|
101
67
|
|
|
102
|
-
|
|
103
|
-
"s3://${ARTIFACT_BUCKET}/${ARTIFACT_KEY}" \
|
|
104
|
-
--region "$AWS_REGION"
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Deploy the generated CloudFormation template using the restricted execution role captured from the
|
|
108
|
-
core bootstrap stack:
|
|
109
|
-
|
|
110
|
-
```sh
|
|
111
|
-
aws cloudformation deploy \
|
|
112
|
-
--stack-name "$STACK_NAME" \
|
|
113
|
-
--template-file aws-dashboard-release/template.yml \
|
|
114
|
-
--role-arn "$CLOUDFORMATION_EXECUTION_ROLE_ARN" \
|
|
115
|
-
--region "$AWS_REGION" \
|
|
116
|
-
--capabilities CAPABILITY_NAMED_IAM \
|
|
117
|
-
--parameter-overrides file://aws-dashboard-parameters.json \
|
|
118
|
-
--no-fail-on-empty-changeset
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
The stack outputs `ServerFunctionArn`. Integrate that ARN with your protected API Gateway, ALB, or
|
|
122
|
-
other consumer-owned gateway, then verify the protected `/health` endpoint. The template deliberately
|
|
123
|
-
does not grant public Lambda invoke permission.
|
|
124
|
-
|
|
125
|
-
## Operate safely
|
|
126
|
-
|
|
127
|
-
To upgrade, install a newer exact package version and repeat package, upload, and deploy. A change to
|
|
128
|
-
`board.yaml` follows the same path; it does not require a package change.
|
|
129
|
-
|
|
130
|
-
After upgrading, also check the [bootstrap upgrade guidance](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-bootstrap.md#check-the-bootstrap-template-on-package-upgrades).
|
|
131
|
-
Compatible releases may add optional bootstrap capabilities without changing the contract version.
|
|
132
|
-
If your workflow verifies a consumer-owned gateway stack, add `githubOidc.consumerGatewayStackName`
|
|
133
|
-
to the reviewed manifest and update the GitHub OIDC stack; other consumers do not need to rerun
|
|
134
|
-
bootstrap.
|
|
135
|
-
|
|
136
|
-
Tokens belong in runtime secret handling, never in board YAML, `aws-dashboard-parameters.json`, or
|
|
137
|
-
the generated ZIP. See [runtime secrets](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-setup.md#runtime-secrets)
|
|
138
|
-
for the supported secret reference and integration boundary.
|
|
139
|
-
|
|
140
|
-
## Commands and boundaries
|
|
141
|
-
|
|
142
|
-
| Command | Use |
|
|
68
|
+
| The package owns | You own |
|
|
143
69
|
| --- | --- |
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
|
|
|
148
|
-
|
|
|
149
|
-
|
|
70
|
+
| Board validation and Lambda packaging | Board content and source access |
|
|
71
|
+
| Compatible immutable browser assets | The protected gateway and authentication |
|
|
72
|
+
| Private application CloudFormation template | AWS account administration |
|
|
73
|
+
| Restricted bootstrap templates | Secret values and runtime credential loading |
|
|
74
|
+
| Read-only preflight and consistency checks | Reviewing and executing AWS changes |
|
|
75
|
+
|
|
76
|
+
Bootstrap commands never execute mutating AWS operations. They produce plans, parameters, and
|
|
77
|
+
commands for an administrator to review and run explicitly. `bootstrap check` is the named
|
|
78
|
+
read-only live diagnostic used before routine deployments.
|
|
150
79
|
|
|
151
|
-
##
|
|
80
|
+
## References
|
|
152
81
|
|
|
153
82
|
- [Board configuration](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/board-configuration.md)
|
|
154
|
-
- [
|
|
155
|
-
- [
|
|
156
|
-
- [GitHub Actions deployment
|
|
157
|
-
- [Runtime secret integration](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-setup.md#runtime-secrets)
|
|
158
|
-
- [Repository source](https://github.com/robertfmurdock/ze-great-dashboard)
|
|
83
|
+
- [Administrator bootstrap](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-bootstrap.md)
|
|
84
|
+
- [Application deployment](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-setup.md)
|
|
85
|
+
- [GitHub Actions deployment](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-github-actions.md)
|
|
159
86
|
- [Issue tracker](https://github.com/robertfmurdock/ze-great-dashboard/issues)
|
|
160
|
-
- [MIT license](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/LICENSE)
|
|
161
|
-
|
|
162
|
-
The package owns the Lambda deployment artifact. Gateway design, authentication, secret-value
|
|
163
|
-
provisioning, and consumer AWS account administration remain your responsibility.
|
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. */
|