Skip to content

Commit

Permalink
feat: add option to cache resolved output values
Browse files Browse the repository at this point in the history
  • Loading branch information
hmeltaus committed Dec 22, 2024
1 parent e47d2e8 commit d4edb25
Show file tree
Hide file tree
Showing 21 changed files with 311 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
commandRole: arn:aws:iam::{{ var.ACCOUNT_1_ID }}:role/OrganizationAccountAccessRole
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
regions: us-east-1
template: stack1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
regions: eu-west-1
template: stack2.yml
parameters:
Code:
resolver: external-stack-output
stack: account-a-stack1
region: us-east-1
output: MyCode
confidential: true
cache: true
depends: /account-a/stack1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
commandRole: arn:aws:iam::{{ var.ACCOUNT_2_ID }}:role/OrganizationAccountAccessRole
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
regions: us-east-1
template: stack3.yml
parameters:
Code:
resolver: external-stack-output
stack: account-a-stack1
output: MyCode
commandRole: arn:aws:iam::{{ var.ACCOUNT_1_ID }}:role/OrganizationAccountAccessRole
cache: true
Code2:
resolver: external-stack-output
stack: account-c-stack4
output: MyCode
commandRole: arn:aws:iam::{{ var.ACCOUNT_3_ID }}:role/OrganizationAccountAccessRole
region: eu-north-1
cache: true
depends:
- /account-a/stack1.yml
- /account-c/stack4.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
regions: us-east-1
template: stack5.yml
parameters:
Code3:
resolver: external-stack-output
stack: account-c-stack4
output: MyCode
commandRole: arn:aws:iam::{{ var.ACCOUNT_3_ID }}:role/OrganizationAccountAccessRole
region: eu-north-1
cache: true
Code4:
resolver: external-stack-output
stack: account-a-stack1
output: MyCode
commandRole: arn:aws:iam::{{ var.ACCOUNT_1_ID }}:role/OrganizationAccountAccessRole
cache: true
depends:
- /account-a/stack1.yml
- /account-c/stack4.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
commandRole: arn:aws:iam::{{ var.ACCOUNT_3_ID }}:role/OrganizationAccountAccessRole
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
regions: eu-north-1
template: stack4.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Resources:
LogGroup:
Type: AWS::Logs::LogGroup
Properties: {}
Outputs:
MyCode:
Description: Code
Value: 123456789
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Parameters:
Code:
Type: String
Description: Code
Resources:
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub log-group-${Code}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Parameters:
Code:
Type: String
Description: Code
AllowedValues:
- "123456789"
Code2:
Type: String
Description: Code
AllowedValues:
- Reggae
Resources:
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub log-group-${Code}-${Code2}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Resources:
LogGroup:
Type: AWS::Logs::LogGroup
Properties: {}
Outputs:
MyCode:
Description: Code
Value: Reggae
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Parameters:
Code3:
Type: String
Description: Code
AllowedValues:
- Reggae
Code4:
Type: String
Description: Code
AllowedValues:
- "123456789"
Resources:
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub log-group-${Code3}-${Code4}-3
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* @testenv-recycler-count 3
*/

import {
executeDeployStacksCommand,
executeUndeployStacksCommand,
} from "../../src/commands/stacks.js"

const projectDir = `${process.cwd()}/integration-test/configs/resolvers/external-stack-output-with-cache`
const stacks = [
{
stackName: "account-a-stack1",
stackPath: "/account-a/stack1.yml/us-east-1",
},
{
stackName: "account-a-stack2",
stackPath: "/account-a/stack2.yml/eu-west-1",
},
{
stackName: "account-b-stack3",
stackPath: "/account-b/stack3.yml/us-east-1",
},
{
stackName: "account-b-stack5",
stackPath: "/account-b/stack5.yml/us-east-1",
},
{
stackName: "account-c-stack4",
stackPath: "/account-c/stack4.yml/eu-north-1",
},
]

describe("External stack output resolver with cache", () => {
test("Deploy", () =>
executeDeployStacksCommand({ projectDir, logLevel: "debug" })
.expectCommandToSucceed()
.expectStackCreateSuccess(...stacks)
.assert())

test("Undeploy", () =>
executeUndeployStacksCommand({ projectDir })
.expectCommandToSucceed()
.expectStackDeleteSuccess(...stacks)
.assert())
})
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"build": "tsc",
"test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest --selectProjects test --maxWorkers=2 --ci --verbose",
"integration-test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest --selectProjects integration-test --maxWorkers=5 --ci --verbose",
"single-integration-test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest --selectProjects integration-test --ci --verbose -i integration-test/test/emit/emit-multiple.test.ts",
"single-integration-test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest --selectProjects integration-test --ci --verbose -i integration-test/test/resolvers/external-stack-output-with-cache.test.ts",
"clean": "rm -f package-lock.json && rm -rf node_modules && rm -rf dist",
"clean-build": "npm run clean && npm install && npm run build",
"depcheck": "depcheck"
Expand Down
16 changes: 14 additions & 2 deletions src/caches/cache.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
export interface Cache {
readonly get: (key: string) => Promise<string | undefined>
readonly put: (key: string, value: string) => Promise<void>
readonly get: (key: string) => Promise<unknown>
readonly put: (key: string, value: unknown) => Promise<void>
readonly reset: () => Promise<void>
}

export const inMemoryCache = () => {
const cache = new Map<string, unknown>()

return {
get: async (key: string) => cache.get(key),
put: async (key: string, value: unknown) => {
cache.set(key, value)
},
reset: async () => cache.clear(),
}
}
7 changes: 7 additions & 0 deletions src/context/stacks-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { StackGroup, StackGroupPath } from "../stacks/stack-group.js"
import { InternalStack, Stack, StackPath } from "../stacks/stack.js"
import { TemplateEngine } from "../templating/template-engine.js"
import { CommandContext, InternalCommandContext } from "./command-context.js"
import { Cache } from "../caches/cache.js"

/**
* Provides access to the current stack context and
Expand All @@ -20,6 +21,11 @@ export interface StacksContext extends CommandContext {
*/
readonly templateEngine: TemplateEngine

/**
* Shared cache for values that needs to be persisted for the duration of the current operation.
*/
readonly cache: Cache

/**
* Return a stack by exact path or throw an error if no stack is found.
* The stack path can be relative if stackGroupPath is given.
Expand All @@ -40,6 +46,7 @@ export interface StacksContext extends CommandContext {
}

export interface InternalStacksContext extends InternalCommandContext {
readonly cache: Cache
readonly concurrentStacks: number
readonly credentialManager: CredentialManager
readonly templateEngine: TemplateEngine
Expand Down
Loading

0 comments on commit d4edb25

Please sign in to comment.