@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 CHANGED
@@ -1,163 +1,86 @@
1
- # Ze Great Dashboard AWS deployment
1
+ # Ze Great Dashboard on AWS
2
2
 
3
- `@continuous-excellence/ze-great-dashboard-aws` packages a configured Ze Great Dashboard as an AWS
4
- Lambda deployment. It includes the compatible immutable client, Lambda runtime, CLI, and
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
- It does not create a public endpoint, choose an authentication policy, create a gateway, provide a
8
- secret value, or own consumer AWS infrastructure. You provide the protected gateway and complete the
9
- administrator-owned bootstrap process first.
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
- For a deployment workflow that verifies a consumer-owned gateway stack, configure
12
- `--consumer-gateway-stack gateway-stack-name` during `bootstrap init`. The GitHub OIDC v2 role then
13
- gets only `cloudformation:DescribeStacks` for that exact stack; the package still does not create,
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
- ## Prerequisites
14
+ ## What you need
17
15
 
18
- You need Node.js 22+, npm, the AWS CLI, `jq`, and one AWS Region for the artifact bucket, Lambda,
19
- and application stack. You also need a consumer-owned artifact bucket and the bootstrap-created
20
- restricted roles. Follow the [AWS bootstrap guide](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-bootstrap.md)
21
- before this deployment procedure.
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
- ## Deploy a dashboard
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
- Use an exact package version in a deployment project:
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@1.2.3
42
+ npm install --save-exact @continuous-excellence/ze-great-dashboard-aws
29
43
  ```
30
44
 
31
- Create `board.yaml`. This small configuration has one GitHub Actions panel and one HTTP value panel;
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
- Generate the application parameters from the non-secret `dashboard-bootstrap.json` created during
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
- Upload the generated ZIP to the bucket and key specified by the parameter file and release metadata:
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
- ```sh
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
- aws s3 cp aws-dashboard-release/lambda.zip \
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
- | `doctor` | Read-only preflight for an existing parameter file. |
145
- | `parameters` | Generate or update application CloudFormation parameters. |
146
- | `package` | Validate board YAML and build a deployable Lambda release. |
147
- | `bootstrap` | Produce bootstrap templates, parameters, preflight, and guidance; administrators run AWS commands explicitly. |
148
- | `publish-assets` | Provider-only: publish immutable client assets. Normal consumers use the hosted client. |
149
- | `deploy` | Provider-only: automation helper for a provider-managed asset and Lambda deployment. |
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
- ## Further reading and support boundary
80
+ ## References
152
81
 
153
82
  - [Board configuration](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/board-configuration.md)
154
- - [AWS bootstrap](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-bootstrap.md)
155
- - [Consumer deployment and CI setup](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-setup.md)
156
- - [GitHub Actions deployment workflow YAML example](https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/aws-setup.md#github-actions)
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.
@@ -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.1' }
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>;
@@ -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. */