Skip to content

Commit

Permalink
docs(ssm): document how to use valueFromLookup for specific value for…
Browse files Browse the repository at this point in the history
…mats (aws#21520)

`StringParameter.valueFromLookup` can be used to retrieve a string
value, but that value could be in any format and there are times where
it is provided as input to properties that require a specific format
(i.e. arn format). Because of the way that lookups are resolved, it is
possible for the initial value to be the dummy value
`dummy-value-for-${parameterName}` which might cause synth errors.

Since there is no way for the CDK to know _how_ you will use the
returned value, we can't really add logic to specifically handle edge
cases. For example, we could have `valueFromLookup` always return a
token, but then it would no longer be able to be used in cases where a
`string` is required. See aws#8699 (comment)
for a good analysis.

This PR adds documentation instructing users how to handle these use
cases.

closes aws#8699, aws#9138


----

### All Submissions:

* [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
corymhall authored and josephedward committed Aug 30, 2022
1 parent e485d80 commit 33030e0
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
51 changes: 51 additions & 0 deletions packages/@aws-cdk/aws-ssm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,56 @@ your CDK app by using `ssm.StringParameter.fromStringParameterAttributes`:

[using SSM parameter](test/integ.parameter-store-string.lit.ts)

### Lookup existing parameters

You can also use an existing parameter by looking up the parameter from the AWS environment.
This method uses AWS API calls to lookup the value from SSM during synthesis.

```ts
const stringValue = ssm.StringParameter.valueFromLookup(stack, '/My/Public/Parameter');
```

When using `valueFromLookup` an initial value of 'dummy-value-for-${parameterName}'
(`dummy-value-for-/My/Public/Parameter` in the above example)
is returned prior to the lookup being performed. This can lead to errors if you are using this
value in places that require a certain format. For example if you have stored the ARN for a SNS
topic in a SSM Parameter which you want to lookup and provide to `Topic.fromTopicArn()`

```ts
const arnLookup = ssm.StringParameter.valueFromLookup(this, '/my/topic/arn');
sns.Topic.fromTopicArn(this, 'Topic', arnLookup);
```

Initially `arnLookup` will be equal to `dummy-value-for-/my/topic/arn` which will cause
`Topic.fromTopicArn` to throw an error indicating that the value is not in `arn` format.

For these use cases you need to handle the `dummy-value` in your code. For example:

```ts
const arnLookup = ssm.StringParameter.valueFromLookup(this, '/my/topic/arn');
let arnLookupValue: string;
if (arnLookup.includes('dummy-value')) {
arnLookupValue = this.formatArn({
service: 'sns',
resource: 'topic',
resourceName: arnLookup,
});

} else {
arnLookupValue = arnLookup;
}

sns.Topic.fromTopicArn(this, 'Topic', arnLookupValue);
```

Alternatively, if the property supports tokens you can convert the parameter value into a token
to be resolved _after_ the lookup has been completed.

```ts
const arnLookup = ssm.StringParameter.valueFromLookup(this, '/my/role/arn');
iam.Role.fromRoleArn(this, 'role', Lazy.string({ produce: () => arnLookup }));
```

## Creating new SSM Parameters in your CDK app

You can create either `ssm.StringParameter` or `ssm.StringListParameter`s in
Expand All @@ -43,3 +93,4 @@ new ssm.StringParameter(this, 'Parameter', {
When specifying an `allowedPattern`, the values provided as string literals
are validated against the pattern and an exception is raised if a value
provided does not comply.

4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-ssm/rosetta/default.ts-fixture
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Fixture with packages imported, but nothing else
import { Construct } from 'constructs';
import { Stack } from '@aws-cdk/core';
import { Stack, Lazy } from '@aws-cdk/core';
import * as ssm from '@aws-cdk/aws-ssm';
import * as sns from '@aws-cdk/aws-sns';
import * as iam from '@aws-cdk/aws-iam';

class Fixture extends Stack {
constructor(scope: Construct, id: string) {
Expand Down

0 comments on commit 33030e0

Please sign in to comment.