@devramps/cli 0.1.22 → 0.1.23

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.
Files changed (2) hide show
  1. package/dist/index.js +53 -35
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1556,25 +1556,35 @@ function addOidcProviderResource(template, conditional = true, oidcProviderUrl)
1556
1556
  }
1557
1557
  };
1558
1558
  }
1559
- function buildOidcTrustPolicy(accountId, subject, oidcProviderUrl) {
1559
+ function buildOidcTrustPolicy(accountId, subject, oidcProviderUrl, additionalTrustedAccounts) {
1560
1560
  const providerUrl = oidcProviderUrl || OIDC_PROVIDER_URL;
1561
- return {
1562
- Version: "2012-10-17",
1563
- Statement: [
1564
- {
1565
- Effect: "Allow",
1566
- Principal: {
1567
- Federated: `arn:aws:iam::${accountId}:oidc-provider/${providerUrl}`
1568
- },
1569
- Action: "sts:AssumeRoleWithWebIdentity",
1570
- Condition: {
1571
- StringEquals: {
1572
- [`${providerUrl}:sub`]: subject,
1573
- [`${providerUrl}:aud`]: "sts.amazonaws.com"
1574
- }
1561
+ const statements = [
1562
+ {
1563
+ Effect: "Allow",
1564
+ Principal: {
1565
+ Federated: `arn:aws:iam::${accountId}:oidc-provider/${providerUrl}`
1566
+ },
1567
+ Action: "sts:AssumeRoleWithWebIdentity",
1568
+ Condition: {
1569
+ StringEquals: {
1570
+ [`${providerUrl}:sub`]: subject,
1571
+ [`${providerUrl}:aud`]: "sts.amazonaws.com"
1575
1572
  }
1576
1573
  }
1577
- ]
1574
+ }
1575
+ ];
1576
+ if (additionalTrustedAccounts && additionalTrustedAccounts.length > 0) {
1577
+ statements.push({
1578
+ Effect: "Allow",
1579
+ Principal: {
1580
+ AWS: additionalTrustedAccounts.map((id) => `arn:aws:iam::${id}:root`)
1581
+ },
1582
+ Action: "sts:AssumeRole"
1583
+ });
1584
+ }
1585
+ return {
1586
+ Version: "2012-10-17",
1587
+ Statement: statements
1578
1588
  };
1579
1589
  }
1580
1590
  function createIamRoleResource(roleName, trustPolicy, policies, additionalTags = []) {
@@ -1938,7 +1948,7 @@ function createTerraformStateBucketPolicy(bucketName, cicdAccountId, allowedAcco
1938
1948
 
1939
1949
  // src/templates/org-stack.ts
1940
1950
  function generateOrgStackTemplate(options) {
1941
- const { orgSlug, cicdAccountId, targetAccountIds, oidcProviderUrl } = options;
1951
+ const { orgSlug, cicdAccountId, targetAccountIds, oidcProviderUrl, additionalTrustedAccounts } = options;
1942
1952
  const template = createBaseTemplate(`DevRamps Org Stack for ${orgSlug}`);
1943
1953
  const kmsKeyPolicy = buildKmsKeyPolicy(cicdAccountId, targetAccountIds);
1944
1954
  template.Resources.DevRampsKMSKey = createKmsKeyResource(
@@ -1968,7 +1978,7 @@ function generateOrgStackTemplate(options) {
1968
1978
  PolicyDocument: bucketPolicy
1969
1979
  }
1970
1980
  };
1971
- const trustPolicy = buildOidcTrustPolicy(cicdAccountId, `org:${orgSlug}/cicd`, oidcProviderUrl);
1981
+ const trustPolicy = buildOidcTrustPolicy(cicdAccountId, `org:${orgSlug}/cicd`, oidcProviderUrl, additionalTrustedAccounts);
1972
1982
  const orgRolePolicies = buildOrgRolePolicies(orgSlug);
1973
1983
  template.Resources.DevRampsCICDDeploymentRole = createIamRoleResource(
1974
1984
  getOrgRoleName(),
@@ -2433,13 +2443,14 @@ function generateStageStackTemplate(options) {
2433
2443
  additionalPolicies,
2434
2444
  dockerArtifacts,
2435
2445
  bundleArtifacts,
2436
- oidcProviderUrl
2446
+ oidcProviderUrl,
2447
+ additionalTrustedAccounts
2437
2448
  } = options;
2438
2449
  const template = createBaseTemplate(
2439
2450
  `DevRamps Stage Stack for ${pipelineSlug}/${stageName}`
2440
2451
  );
2441
2452
  const roleName = generateStageRoleName(pipelineSlug, stageName);
2442
- const trustPolicy = buildStageTrustPolicy(accountId, orgSlug, pipelineSlug, oidcProviderUrl);
2453
+ const trustPolicy = buildStageTrustPolicy(accountId, orgSlug, pipelineSlug, oidcProviderUrl, additionalTrustedAccounts);
2443
2454
  const policies = buildStagePolicies(steps, additionalPolicies);
2444
2455
  template.Resources.StageDeploymentRole = createIamRoleResource(
2445
2456
  roleName,
@@ -2524,9 +2535,9 @@ function generateStageStackTemplate(options) {
2524
2535
  }
2525
2536
  return template;
2526
2537
  }
2527
- function buildStageTrustPolicy(accountId, orgSlug, pipelineSlug, oidcProviderUrl) {
2538
+ function buildStageTrustPolicy(accountId, orgSlug, pipelineSlug, oidcProviderUrl, additionalTrustedAccounts) {
2528
2539
  const subject = `org:${orgSlug}/pipeline:${pipelineSlug}`;
2529
- return buildOidcTrustPolicy(accountId, subject, oidcProviderUrl);
2540
+ return buildOidcTrustPolicy(accountId, subject, oidcProviderUrl, additionalTrustedAccounts);
2530
2541
  }
2531
2542
  function buildStagePolicies(steps, additionalPolicies) {
2532
2543
  const policies = [];
@@ -2595,12 +2606,12 @@ function buildStagePolicies(steps, additionalPolicies) {
2595
2606
 
2596
2607
  // src/templates/import-stack.ts
2597
2608
  function generateImportStackTemplate(options) {
2598
- const { pipelineSlug, orgSlug, accountId, oidcProviderUrl } = options;
2609
+ const { pipelineSlug, orgSlug, accountId, oidcProviderUrl, additionalTrustedAccounts } = options;
2599
2610
  const template = createBaseTemplate(
2600
2611
  `DevRamps Import Stack for ${pipelineSlug} - grants read access for artifact imports`
2601
2612
  );
2602
2613
  const roleName = generateImportRoleName(pipelineSlug);
2603
- const trustPolicy = buildOidcTrustPolicy(accountId, `org:${orgSlug}/cicd`, oidcProviderUrl);
2614
+ const trustPolicy = buildOidcTrustPolicy(accountId, `org:${orgSlug}/cicd`, oidcProviderUrl, additionalTrustedAccounts);
2604
2615
  const policies = buildImportRolePolicies();
2605
2616
  template.Resources.ImportRole = createIamRoleResource(
2606
2617
  roleName,
@@ -2778,7 +2789,8 @@ async function bootstrapCommand(options) {
2778
2789
  process.exit(0);
2779
2790
  }
2780
2791
  const oidcProviderUrl = getOidcProviderUrlFromEndpoint(options.endpointOverride);
2781
- await executeDeployment(plan, pipelines, pipelineArtifacts, authData, identity.accountId, options, oidcProviderUrl);
2792
+ const additionalTrustedAccounts = options.additionalTrustedAccounts ? options.additionalTrustedAccounts.split(",").map((s) => s.trim()) : void 0;
2793
+ await executeDeployment(plan, pipelines, pipelineArtifacts, authData, identity.accountId, options, oidcProviderUrl, additionalTrustedAccounts);
2782
2794
  } catch (error2) {
2783
2795
  if (error2 instanceof DevRampsError) {
2784
2796
  error(error2.message);
@@ -3051,7 +3063,7 @@ async function confirmDeploymentPlan(plan) {
3051
3063
  ]
3052
3064
  });
3053
3065
  }
3054
- async function executeDeployment(plan, pipelines, pipelineArtifacts, authData, currentAccountId, options, oidcProviderUrl) {
3066
+ async function executeDeployment(plan, pipelines, pipelineArtifacts, authData, currentAccountId, options, oidcProviderUrl, additionalTrustedAccounts) {
3055
3067
  const results = { success: 0, failed: 0 };
3056
3068
  const remainingStacks = 1 + plan.pipelineStacks.length + plan.stageStacks.length + plan.importStacks.length;
3057
3069
  newline();
@@ -3114,7 +3126,7 @@ async function executeDeployment(plan, pipelines, pipelineArtifacts, authData, c
3114
3126
  mainProgress.start();
3115
3127
  const orgPromise = (async () => {
3116
3128
  try {
3117
- await deployOrgStack(plan, pipelines, authData, currentAccountId, options, oidcProviderUrl);
3129
+ await deployOrgStack(plan, pipelines, authData, currentAccountId, options, oidcProviderUrl, additionalTrustedAccounts);
3118
3130
  return { stack: plan.orgStack.stackName, success: true };
3119
3131
  } catch (error2) {
3120
3132
  return {
@@ -3138,7 +3150,7 @@ async function executeDeployment(plan, pipelines, pipelineArtifacts, authData, c
3138
3150
  });
3139
3151
  const stagePromises = plan.stageStacks.map(async (stack) => {
3140
3152
  try {
3141
- await deployStageStack(stack, authData, currentAccountId, options, oidcProviderUrl);
3153
+ await deployStageStack(stack, authData, currentAccountId, options, oidcProviderUrl, additionalTrustedAccounts);
3142
3154
  return { stack: stack.stackName, success: true };
3143
3155
  } catch (error2) {
3144
3156
  return {
@@ -3150,7 +3162,7 @@ async function executeDeployment(plan, pipelines, pipelineArtifacts, authData, c
3150
3162
  });
3151
3163
  const importPromises = plan.importStacks.map(async (stack) => {
3152
3164
  try {
3153
- await deployImportStack(stack, currentAccountId, options, oidcProviderUrl);
3165
+ await deployImportStack(stack, currentAccountId, options, oidcProviderUrl, additionalTrustedAccounts);
3154
3166
  return { stack: `${stack.stackName} (${stack.accountId})`, success: true };
3155
3167
  } catch (error2) {
3156
3168
  return {
@@ -3187,7 +3199,7 @@ async function executeDeployment(plan, pipelines, pipelineArtifacts, authData, c
3187
3199
  process.exit(1);
3188
3200
  }
3189
3201
  }
3190
- async function deployOrgStack(plan, pipelines, authData, currentAccountId, options, oidcProviderUrl) {
3202
+ async function deployOrgStack(plan, pipelines, authData, currentAccountId, options, oidcProviderUrl, additionalTrustedAccounts) {
3191
3203
  const { orgSlug, cicdAccountId, cicdRegion } = authData;
3192
3204
  const credentials = cicdAccountId !== currentAccountId ? (await assumeRoleForAccount({
3193
3205
  targetAccountId: cicdAccountId,
@@ -3218,7 +3230,8 @@ async function deployOrgStack(plan, pipelines, authData, currentAccountId, optio
3218
3230
  orgSlug,
3219
3231
  cicdAccountId,
3220
3232
  targetAccountIds,
3221
- oidcProviderUrl
3233
+ oidcProviderUrl,
3234
+ additionalTrustedAccounts
3222
3235
  });
3223
3236
  const deployOptions = {
3224
3237
  stackName: plan.orgStack.stackName,
@@ -3270,7 +3283,7 @@ async function deployAccountStack(stack, currentAccountId, options, oidcProvider
3270
3283
  await previewStackChanges(deployOptions);
3271
3284
  await deployStack(deployOptions);
3272
3285
  }
3273
- async function deployStageStack(stack, authData, currentAccountId, options, oidcProviderUrl) {
3286
+ async function deployStageStack(stack, authData, currentAccountId, options, oidcProviderUrl, additionalTrustedAccounts) {
3274
3287
  const credentials = stack.accountId !== currentAccountId ? (await assumeRoleForAccount({
3275
3288
  targetAccountId: stack.accountId,
3276
3289
  currentAccountId,
@@ -3285,7 +3298,8 @@ async function deployStageStack(stack, authData, currentAccountId, options, oidc
3285
3298
  additionalPolicies: stack.additionalPolicies,
3286
3299
  dockerArtifacts: stack.dockerArtifacts,
3287
3300
  bundleArtifacts: stack.bundleArtifacts,
3288
- oidcProviderUrl
3301
+ oidcProviderUrl,
3302
+ additionalTrustedAccounts
3289
3303
  });
3290
3304
  const deployOptions = {
3291
3305
  stackName: stack.stackName,
@@ -3297,7 +3311,7 @@ async function deployStageStack(stack, authData, currentAccountId, options, oidc
3297
3311
  await previewStackChanges(deployOptions);
3298
3312
  await deployStack(deployOptions);
3299
3313
  }
3300
- async function deployImportStack(stack, currentAccountId, options, oidcProviderUrl) {
3314
+ async function deployImportStack(stack, currentAccountId, options, oidcProviderUrl, additionalTrustedAccounts) {
3301
3315
  const credentials = stack.accountId !== currentAccountId ? (await assumeRoleForAccount({
3302
3316
  targetAccountId: stack.accountId,
3303
3317
  currentAccountId,
@@ -3307,7 +3321,8 @@ async function deployImportStack(stack, currentAccountId, options, oidcProviderU
3307
3321
  pipelineSlug: stack.pipelineSlug,
3308
3322
  orgSlug: stack.orgSlug,
3309
3323
  accountId: stack.accountId,
3310
- oidcProviderUrl
3324
+ oidcProviderUrl,
3325
+ additionalTrustedAccounts
3311
3326
  });
3312
3327
  const deployOptions = {
3313
3328
  stackName: stack.stackName,
@@ -3337,5 +3352,8 @@ program.command("bootstrap").description("Bootstrap IAM roles in target AWS acco
3337
3352
  ).option(
3338
3353
  "--endpoint-override <url>",
3339
3354
  "Override the DevRamps API endpoint (for testing, e.g., http://localhost:3000)"
3355
+ ).option(
3356
+ "--additional-trusted-accounts <accounts>",
3357
+ "Comma-separated AWS account IDs to add to role trust policies (for local dev testing)"
3340
3358
  ).action(bootstrapCommand);
3341
3359
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devramps/cli",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "description": "DevRamps CLI - Bootstrap AWS infrastructure for CI/CD pipelines",
5
5
  "main": "dist/index.js",
6
6
  "bin": {