Skip to content

Commit

Permalink
Add support for resolving dynamic ssm values (#268)
Browse files Browse the repository at this point in the history
  • Loading branch information
corymhall authored Dec 3, 2024
1 parent f80cb73 commit 1b6681e
Show file tree
Hide file tree
Showing 14 changed files with 3,283 additions and 146 deletions.
14 changes: 14 additions & 0 deletions examples/ec2-instance/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as aws from '@pulumi/aws';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
Expand All @@ -6,6 +7,7 @@ import * as pulumicdk from '@pulumi/cdk';
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
import * as pulumi from '@pulumi/pulumi';

const region = aws.config.requireRegion();
const config = new pulumi.Config();
const prefix = config.get('prefix') ?? pulumi.getStack();
export class Ec2CdkStack extends pulumicdk.Stack {
Expand Down Expand Up @@ -83,6 +85,18 @@ export class Ec2CdkStack extends pulumicdk.Stack {
new cdk.CfnOutput(this, 'ssh command', {
value: 'ssh -i cdk-key.pem -o IdentitiesOnly=yes ec2-user@' + ec2Instance.instancePublicIp,
});

const ssmName = ec2.AmazonLinuxImage.ssmParameterName({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2023,
cpuType: ec2.AmazonLinuxCpuType.ARM_64,
});
new ec2.Instance(this, 'ssm-instance', {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize.MICRO),
machineImage: ec2.MachineImage.genericLinux({
[region]: `{{resolve:ssm:${ssmName}}}`,
}),
});
}
}

Expand Down
31 changes: 31 additions & 0 deletions integration/examples_nodejs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,37 @@ func TestReplaceOnChanges(t *testing.T) {
integration.ProgramTest(t, &test)
}

func TestSsmDynamic(t *testing.T) {
test := getJSBaseOptions(t).
With(integration.ProgramTestOptions{
Dir: filepath.Join(getCwd(t), "ssm-dynamic"),
EditDirs: []integration.EditDir{
{
Dir: filepath.Join(getCwd(t), "ssm-dynamic/step2"),
Additive: true,
ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
t.Logf("\nOutputs: %v\n\n", stack.Outputs)

stringValue := stack.Outputs["stringValue"].(string)
assert.Equal(t, "testvalue", stringValue)

stringListValue := stack.Outputs["stringListValue"].([]interface{})
assert.Equal(t, []interface{}{"abcd", "xyz"}, stringListValue)

dynamicStringValue := stack.Outputs["dynamicStringValue"].(string)
assert.Equal(t, "testvalue", dynamicStringValue)

dyanmicStringListValue := stack.Outputs["dynamicStringListValue"].([]interface{})
assert.Equal(t, []interface{}{"abcd", "xyz"}, dyanmicStringListValue)

},
},
},
})

integration.ProgramTest(t, &test)
}

func TestRemovalPolicy(t *testing.T) {
// Since we are creating two tests we have to set `NoParallel` on each test
// and set parallel here.
Expand Down
3 changes: 3 additions & 0 deletions integration/ssm-dynamic/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: pulumi-aws-ssm-dynamic
runtime: nodejs
description: ssm-dynamic integration test
35 changes: 35 additions & 0 deletions integration/ssm-dynamic/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as pulumi from '@pulumi/pulumi';
import * as ssm from 'aws-cdk-lib/aws-ssm';
import * as pulumicdk from '@pulumi/cdk';

const config = new pulumi.Config();
const prefix = config.get('prefix') ?? pulumi.getStack();
class SsmDynamicStack extends pulumicdk.Stack {
public readonly stringValue: pulumi.Output<string>;
public readonly stringListValue: pulumi.Output<string[]>;
constructor(app: pulumicdk.App, id: string, options?: pulumicdk.StackOptions) {
super(app, id, options);

const stringParam = new ssm.StringParameter(this, 'testparam', {
parameterName: `${prefix}-param`,
stringValue: 'testvalue',
});
this.stringValue = this.asOutput(stringParam.stringValue);

const listParam = new ssm.StringListParameter(this, 'testparamlist', {
parameterName: `${prefix}-listparam`,
stringListValue: ['abcd', 'xyz'],
});
this.stringListValue = this.asOutput(listParam.stringListValue);
}
}

const app = new pulumicdk.App('app', (scope: pulumicdk.App) => {
const stack = new SsmDynamicStack(scope, `${prefix}-misc`);
return {
stringValue: stack.stringValue,
stringListValue: stack.stringListValue,
};
});
export const stringValue = app.outputs['stringValue'];
export const stringListValue = app.outputs['stringListValue'];
15 changes: 15 additions & 0 deletions integration/ssm-dynamic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "pulumi-aws-cdk",
"devDependencies": {
"@types/node": "^10.0.0"
},
"dependencies": {
"@pulumi/aws": "6.61.0",
"@pulumi/aws-native": "^1.11.0",
"@pulumi/cdk": "^1.0.0",
"@pulumi/pulumi": "^3.0.0",
"aws-cdk-lib": "2.156.0",
"constructs": "10.3.0",
"esbuild": "^0.24.0"
}
}
57 changes: 57 additions & 0 deletions integration/ssm-dynamic/step2/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import * as pulumi from '@pulumi/pulumi';
import * as ssm from 'aws-cdk-lib/aws-ssm';
import * as pulumicdk from '@pulumi/cdk';
import { CfnDynamicReference, CfnDynamicReferenceService } from 'aws-cdk-lib';

const config = new pulumi.Config();
const prefix = config.get('prefix') ?? pulumi.getStack();
class SsmDynamicStack extends pulumicdk.Stack {
public readonly stringValue: pulumi.Output<string>;
public readonly stringListValue: pulumi.Output<string[]>;
public readonly dynamicStringValue: pulumi.Output<string>;
public readonly dynamicStringListValue: pulumi.Output<string[]>;
constructor(app: pulumicdk.App, id: string, options?: pulumicdk.StackOptions) {
super(app, id, options);

const stringParam = new ssm.StringParameter(this, 'testparam', {
parameterName: `${prefix}-param`,
stringValue: 'testvalue',
});
this.stringValue = this.asOutput(stringParam.stringValue);

const listParam = new ssm.StringListParameter(this, 'testparamlist', {
parameterName: `${prefix}-listparam`,
stringListValue: ['abcd', 'xyz'],
});
this.stringListValue = this.asOutput(listParam.stringListValue);

const stringValue = new CfnDynamicReference(CfnDynamicReferenceService.SSM, `${prefix}-param`).toString();
const stringDynamicParam = new ssm.StringParameter(this, 'stringDynamicParam', {
stringValue: stringValue,
});
this.dynamicStringValue = this.asOutput(stringDynamicParam.stringValue);

const stringListValue = new CfnDynamicReference(
CfnDynamicReferenceService.SSM,
`${prefix}-listparam`,
).toString();
const stringListDynamicParam = new ssm.StringParameter(this, 'stringListDynamicParam', {
stringValue: stringListValue,
});
this.dynamicStringListValue = this.asOutput(stringListDynamicParam.stringValue).apply((v) => v.split(','));
}
}

const app = new pulumicdk.App('app', (scope: pulumicdk.App) => {
const stack = new SsmDynamicStack(scope, `${prefix}-misc`);
return {
stringValue: stack.stringValue,
stringListValue: stack.stringListValue,
dynamicStringValue: stack.dynamicStringValue,
dynamicStringListValue: stack.dynamicStringListValue,
};
});
export const stringValue = app.outputs['stringValue'];
export const stringListValue = app.outputs['stringListValue'];
export const dynamicStringValue = app.outputs['dynamicStringValue'];
export const dynamicStringListValue = app.outputs['dynamicStringListValue'];
18 changes: 18 additions & 0 deletions integration/ssm-dynamic/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2019",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"include": [
"./*.ts"
]
}
Loading

0 comments on commit 1b6681e

Please sign in to comment.