@fjall/deploy-core 0.89.4 → 0.89.5
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/src/aws/AwsProvider.d.ts +2 -2
- package/dist/src/aws/SimpleAwsProvider.d.ts +2 -3
- package/dist/src/aws/SimpleAwsProvider.js +1 -4
- package/dist/src/orchestration/applicationDeploy.js +5 -0
- package/dist/src/orchestration/contextHelpers.d.ts +1 -0
- package/dist/src/orchestration/contextHelpers.js +2 -1
- package/dist/src/orchestration/organisationDeploy.js +32 -7
- package/dist/src/services/infrastructure/CdkService.d.ts +1 -0
- package/dist/src/services/infrastructure/CdkService.js +1 -0
- package/dist/src/types/credentials.d.ts +1 -1
- package/dist/src/types/deployment/DeploymentTypes.d.ts +1 -0
- package/dist/src/types/params.d.ts +2 -0
- package/package.json +4 -4
|
@@ -12,8 +12,8 @@ export interface AwsProvider {
|
|
|
12
12
|
getClient<T>(ClientClass: AwsSdkClientConstructor<T>): T;
|
|
13
13
|
/** AWS region for this context. */
|
|
14
14
|
getRegion(): string;
|
|
15
|
-
/** AWS account ID (
|
|
16
|
-
getAccountId(): string
|
|
15
|
+
/** AWS account ID — always available (callers resolve before calling deploy-core). */
|
|
16
|
+
getAccountId(): string;
|
|
17
17
|
/** Raw credentials for subprocess environments (CDK). */
|
|
18
18
|
getCredentials(): AwsProviderCredentials | undefined;
|
|
19
19
|
/** Export credentials to process.env for spawned subprocesses. */
|
|
@@ -9,13 +9,12 @@ import type { AwsProvider, AwsProviderCredentials, AwsSdkClientConstructor } fro
|
|
|
9
9
|
export declare class SimpleAwsProvider implements AwsProvider {
|
|
10
10
|
private readonly credentials;
|
|
11
11
|
private readonly region;
|
|
12
|
-
private accountId;
|
|
12
|
+
private readonly accountId;
|
|
13
13
|
private readonly clientCache;
|
|
14
14
|
constructor(awsCredentials: AwsCredentials);
|
|
15
15
|
getClient<T>(ClientClass: AwsSdkClientConstructor<T>): T;
|
|
16
16
|
getRegion(): string;
|
|
17
|
-
getAccountId(): string
|
|
18
|
-
setAccountId(accountId: string): void;
|
|
17
|
+
getAccountId(): string;
|
|
19
18
|
getCredentials(): AwsProviderCredentials;
|
|
20
19
|
exportToEnv(): void;
|
|
21
20
|
assumeRole(roleArn: string, sessionName: string): Promise<AwsProviderCredentials>;
|
|
@@ -37,9 +37,6 @@ export class SimpleAwsProvider {
|
|
|
37
37
|
getAccountId() {
|
|
38
38
|
return this.accountId;
|
|
39
39
|
}
|
|
40
|
-
setAccountId(accountId) {
|
|
41
|
-
this.accountId = accountId;
|
|
42
|
-
}
|
|
43
40
|
getCredentials() {
|
|
44
41
|
return this.credentials;
|
|
45
42
|
}
|
|
@@ -59,7 +56,7 @@ export class SimpleAwsProvider {
|
|
|
59
56
|
const response = await stsClient.send(new AssumeRoleCommand({
|
|
60
57
|
RoleArn: roleArn,
|
|
61
58
|
RoleSessionName: sessionName
|
|
62
|
-
}));
|
|
59
|
+
}), { abortSignal: AbortSignal.timeout(30_000) });
|
|
63
60
|
const assumed = response.Credentials;
|
|
64
61
|
if (!assumed?.AccessKeyId || !assumed?.SecretAccessKey) {
|
|
65
62
|
throw new Error(`AssumeRole for ${roleArn} returned incomplete credentials`);
|
|
@@ -21,6 +21,11 @@ export async function deployApplication(params, services, operation) {
|
|
|
21
21
|
target: operation.appName,
|
|
22
22
|
path: operation.path,
|
|
23
23
|
region: services.awsProvider.getRegion(),
|
|
24
|
+
callerIdentity: {
|
|
25
|
+
Account: services.awsProvider.getAccountId(),
|
|
26
|
+
Arn: "",
|
|
27
|
+
UserId: ""
|
|
28
|
+
},
|
|
24
29
|
...buildParamsContext(params)
|
|
25
30
|
}, {
|
|
26
31
|
verbose: options?.verbose,
|
|
@@ -42,7 +42,7 @@ function buildOrgContext(params, services, operation, deployType, accountName) {
|
|
|
42
42
|
region: services.awsProvider.getRegion(),
|
|
43
43
|
accountName,
|
|
44
44
|
callerIdentity: {
|
|
45
|
-
Account: services.awsProvider.getAccountId()
|
|
45
|
+
Account: services.awsProvider.getAccountId(),
|
|
46
46
|
Arn: "",
|
|
47
47
|
UserId: ""
|
|
48
48
|
},
|
|
@@ -52,16 +52,37 @@ function buildOrgContext(params, services, operation, deployType, accountName) {
|
|
|
52
52
|
infraOnly: params.options?.infraOnly
|
|
53
53
|
}, params.orgConfig);
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Infrastructure deployment step names — match the webapp's
|
|
57
|
+
* EXPECTED_INFRASTRUCTURE_STEPS exactly so the UI timeline lights up.
|
|
58
|
+
*/
|
|
59
|
+
const INFRA_STEPS = {
|
|
60
|
+
CONNECT: { id: "connect", name: "Connect securely" },
|
|
61
|
+
PREPARE: { id: "prepare", name: "Prepare environment" },
|
|
62
|
+
DEPLOY: { id: "deploy", name: "Deploy infrastructure" },
|
|
63
|
+
MONITORING: { id: "monitoring", name: "Enable monitoring" }
|
|
64
|
+
};
|
|
65
|
+
const INFRA_STEP_TOTAL = 4;
|
|
55
66
|
/**
|
|
56
67
|
* Deploy a single organisation component (platform or account).
|
|
68
|
+
*
|
|
69
|
+
* Emits 4 named steps matching the webapp's expected infrastructure
|
|
70
|
+
* timeline: Connect securely → Prepare environment → Deploy
|
|
71
|
+
* infrastructure → Enable monitoring.
|
|
57
72
|
*/
|
|
58
73
|
async function deploySingleComponent(params, services, operation, deployType, startTime) {
|
|
59
74
|
const { callbacks } = params;
|
|
75
|
+
// Step 1: Connect securely — already seeded by the webapp trigger.
|
|
76
|
+
// Complete it now: credentials are available by the time deploy-core runs.
|
|
77
|
+
callbacks.onStepComplete?.(INFRA_STEPS.CONNECT.id, INFRA_STEPS.CONNECT.name, "completed", 0, INFRA_STEP_TOTAL);
|
|
78
|
+
// Step 2: Prepare environment (synth + bootstrap)
|
|
79
|
+
callbacks.onStepStart?.(INFRA_STEPS.PREPARE.id, INFRA_STEPS.PREPARE.name, 1, INFRA_STEP_TOTAL);
|
|
60
80
|
const context = buildOrgContext(params, services, operation, deployType, deployType === "account" ? operation.target : undefined);
|
|
61
81
|
// Synth
|
|
62
82
|
callbacks.onLog?.(`Synthesising ${deployType} infrastructure…`, "info");
|
|
63
83
|
const synthResult = await services.cdkService.runCdkSynth(context, (chunk) => callbacks.onCdkOutput?.(chunk, "synth"));
|
|
64
84
|
if (!synthResult.success) {
|
|
85
|
+
callbacks.onStepComplete?.(INFRA_STEPS.PREPARE.id, INFRA_STEPS.PREPARE.name, "error", 1, INFRA_STEP_TOTAL);
|
|
65
86
|
const error = new Error(`CDK synthesis failed: ${synthResult.error}`);
|
|
66
87
|
callbacks.onError?.(error);
|
|
67
88
|
return failure(error);
|
|
@@ -71,24 +92,28 @@ async function deploySingleComponent(params, services, operation, deployType, st
|
|
|
71
92
|
const bootstrapResult = await services.cdkService.runCdkBootstrap(context, (chunk) => callbacks.onOutput?.(chunk));
|
|
72
93
|
if (!bootstrapResult.success) {
|
|
73
94
|
callbacks.onCDKBootstrap?.("failed");
|
|
95
|
+
callbacks.onStepComplete?.(INFRA_STEPS.PREPARE.id, INFRA_STEPS.PREPARE.name, "error", 1, INFRA_STEP_TOTAL);
|
|
74
96
|
const error = new Error(`Bootstrap failed: ${bootstrapResult.error}`);
|
|
75
97
|
callbacks.onError?.(error);
|
|
76
98
|
return failure(error);
|
|
77
99
|
}
|
|
78
100
|
callbacks.onCDKBootstrap?.("complete");
|
|
79
|
-
|
|
101
|
+
callbacks.onStepComplete?.(INFRA_STEPS.PREPARE.id, INFRA_STEPS.PREPARE.name, "completed", 1, INFRA_STEP_TOTAL);
|
|
102
|
+
// Step 3: Deploy infrastructure
|
|
80
103
|
const stackName = getOrganisationStackName(operation.type);
|
|
81
|
-
|
|
82
|
-
const stepName = `Deploying ${deployType} infrastructure`;
|
|
83
|
-
callbacks.onStepStart?.(stepId, stepName, 0, 1);
|
|
104
|
+
callbacks.onStepStart?.(INFRA_STEPS.DEPLOY.id, INFRA_STEPS.DEPLOY.name, 2, INFRA_STEP_TOTAL);
|
|
84
105
|
const deployResult = await services.cdkService.runCdkDeploy(context, stackName, (chunk) => callbacks.onOutput?.(chunk), (event) => callbacks.onResourceProgress?.(event), services.awsProvider);
|
|
85
106
|
if (!deployResult.success) {
|
|
86
|
-
callbacks.onStepComplete?.(
|
|
107
|
+
callbacks.onStepComplete?.(INFRA_STEPS.DEPLOY.id, INFRA_STEPS.DEPLOY.name, "error", 2, INFRA_STEP_TOTAL);
|
|
87
108
|
const error = new Error(deployResult.error);
|
|
88
109
|
callbacks.onError?.(error);
|
|
89
110
|
return failure(error);
|
|
90
111
|
}
|
|
91
|
-
callbacks.onStepComplete?.(
|
|
112
|
+
callbacks.onStepComplete?.(INFRA_STEPS.DEPLOY.id, INFRA_STEPS.DEPLOY.name, "completed", 2, INFRA_STEP_TOTAL);
|
|
113
|
+
// Step 4: Enable monitoring — CloudTrail + alarms are part of the
|
|
114
|
+
// Account stack. Signal post-deploy readiness.
|
|
115
|
+
callbacks.onStepStart?.(INFRA_STEPS.MONITORING.id, INFRA_STEPS.MONITORING.name, 3, INFRA_STEP_TOTAL);
|
|
116
|
+
callbacks.onStepComplete?.(INFRA_STEPS.MONITORING.id, INFRA_STEPS.MONITORING.name, "completed", 3, INFRA_STEP_TOTAL);
|
|
92
117
|
return success({
|
|
93
118
|
target: operation.target,
|
|
94
119
|
deploymentType: "organisation",
|
|
@@ -70,6 +70,7 @@ export class CdkService {
|
|
|
70
70
|
managementAccountId: context.managementAccountId,
|
|
71
71
|
ipamPoolId: context.ipamPoolId,
|
|
72
72
|
fjallOrgId: context.fjallOrgId,
|
|
73
|
+
fjallOidcConfigured: context.fjallOidcConfigured ? "true" : undefined,
|
|
73
74
|
orgConfig: context.orgConfig
|
|
74
75
|
};
|
|
75
76
|
}
|
|
@@ -60,6 +60,8 @@ export interface DeployOptions {
|
|
|
60
60
|
deployOnly?: boolean;
|
|
61
61
|
passThroughCDK?: boolean;
|
|
62
62
|
environment?: string;
|
|
63
|
+
/** Skip OIDC provider creation — set when OIDC is already configured (webapp Quick Create). */
|
|
64
|
+
skipOidc?: boolean;
|
|
63
65
|
}
|
|
64
66
|
export type DeploymentType = "application" | "organisation";
|
|
65
67
|
export interface DeployResult {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/deploy-core",
|
|
3
|
-
"version": "0.89.
|
|
3
|
+
"version": "0.89.5",
|
|
4
4
|
"description": "Shared deployment engine for Fjall — used by CLI and webapp worker",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"@aws-sdk/client-ram": "^3.1009.0",
|
|
33
33
|
"@aws-sdk/client-sso-admin": "^3.1009.0",
|
|
34
34
|
"@aws-sdk/client-sts": "^3.1009.0",
|
|
35
|
-
"@fjall/generator": "^0.89.
|
|
36
|
-
"@fjall/util": "^0.89.
|
|
35
|
+
"@fjall/generator": "^0.89.5",
|
|
36
|
+
"@fjall/util": "^0.89.5",
|
|
37
37
|
"zod": "^4.3.6"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"vitest": "^3.2.3"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "1680c1a0be16950e9e10e571163ccc42198f6a8e"
|
|
43
43
|
}
|