forked from aws/aws-cdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(ssm): malformed ARNs for parameters with physical names that use …
…path notation (aws#4842) * fix(ssm): malformed ARNs for parameters with physical names that use path notation SSM parameter names can have one of two forms: “simpleName” or “/path/name”. This makes it tricky to render an ARN for the parameter is the name is an unresolvable token (such as a “Ref”) because we can’t decide whether a “/“ separator is required in the ARN. The previous implementation assumed "Ref" always returns the name without a "/" prefix, and therefore did not use the "/" separator. This fix will use the physical name itself (if possible) to determine the separator (and also assume that generated names will not use the path notation). The only case where this is impossible is if the physical name is a token (either created or imported), in which case we should be able to synthesize a CloudFormation condition which will parse the token during deployment. This test also adds a validation that verifies that if a physical name is provided and uses path notation, it must begin with a "/". Misc: re-add `install.sh` to call `npx yarn install` * explicit parameterArnSeparator revert attempt to guess parameter name prefix if it's a token since we can't incorporate refs in conditions. Instead, if the parameter name if a token, we expect `parameterArnSeparator` to be explicitly defined and be one of "/" or "". * misc * fix test expectation * add public API doc * add --frozen-lockfile to install.sh * rename "parameterArnSeparator: string" to "simpleName: boolean"
- Loading branch information
1 parent
df6fc58
commit 43f276a
Showing
7 changed files
with
620 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
set -euo pipefail | ||
exec npx yarn install --frozen-lockfile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { IConstruct, Stack, Token } from "@aws-cdk/core"; | ||
|
||
export const AUTOGEN_MARKER = '$$autogen$$'; | ||
|
||
export interface ArnForParameterNameOptions { | ||
readonly physicalName?: string; | ||
readonly simpleName?: boolean; | ||
} | ||
|
||
/** | ||
* Renders an ARN for an SSM parameter given a parameter name. | ||
* @param scope definition scope | ||
* @param parameterName the parameter name to include in the ARN | ||
* @param physicalName optional physical name specified by the user (to auto-detect separator) | ||
*/ | ||
export function arnForParameterName(scope: IConstruct, parameterName: string, options: ArnForParameterNameOptions = { }): string { | ||
const physicalName = options.physicalName; | ||
const nameToValidate = physicalName || parameterName; | ||
|
||
if (!Token.isUnresolved(nameToValidate) && nameToValidate.includes('/') && !nameToValidate.startsWith('/')) { | ||
throw new Error(`Parameter names must be fully qualified (if they include "/" they must also begin with a "/"): ${nameToValidate}`); | ||
} | ||
|
||
return Stack.of(scope).formatArn({ | ||
service: 'ssm', | ||
resource: 'parameter', | ||
sep: isSimpleName() ? '/' : '', | ||
resourceName: parameterName, | ||
}); | ||
|
||
/** | ||
* Determines the ARN separator for this parameter: if we have a concrete | ||
* parameter name (or explicitly defined physical name), we will parse them | ||
* and decide whether a "/" is needed or not. Otherwise, users will have to | ||
* explicitly specify `simpleName` when they import the ARN. | ||
*/ | ||
function isSimpleName(): boolean { | ||
// look for a concrete name as a hint for determining the separator | ||
const concreteName = !Token.isUnresolved(parameterName) ? parameterName : physicalName; | ||
if (!concreteName || Token.isUnresolved(concreteName)) { | ||
|
||
if (options.simpleName === undefined) { | ||
throw new Error(`Unable to determine ARN separator for SSM parameter since the parameter name is an unresolved token. Use "fromAttributes" and specify "simpleName" explicitly`); | ||
} | ||
|
||
return options.simpleName; | ||
} | ||
|
||
const result = !concreteName.startsWith('/'); | ||
|
||
// if users explicitly specify the separator and it conflicts with the one we need, it's an error. | ||
if (options.simpleName !== undefined && options.simpleName !== result) { | ||
|
||
if (concreteName === AUTOGEN_MARKER) { | ||
throw new Error(`If "parameterName" is not explicitly defined, "simpleName" must be "true" or undefined since auto-generated parameter names always have simple names`); | ||
} | ||
|
||
throw new Error(`Parameter name "${concreteName}" is ${result ? 'a simple name' : 'not a simple name'}, but "simpleName" was explicitly set to ${options.simpleName}. Either omit it or set it to ${result}`); | ||
} | ||
|
||
return result; | ||
} | ||
} |
Oops, something went wrong.