-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CLI: way to get outputs from deployed stack #1773
Comments
You can scrape the outputs from the CLI stdout after running > cdk metadata --name MyLoadBalancer
your.dns.name |
Yeah I'm really thinking of the scenario where I go back later after a deploy and need to grab the DNS name. It feels weird to issue a deploy again to get that. Even a list of the outputs would be helpful, since they tend to get auto-named something like ServiceLoadBalancerDNSEC5B149E |
Had the same issue, solved it for now by adding this as a script to the package.json
|
+1 This is a pretty significant challenge when using the CDK programmatically, as the outputs are also randomly named. For example my stack has:
For now I'm relying on manually querying the output from CloudFormation like this:
But the usage of a zero index isn't particularly safe as a new output may be added in the future. However I have no way of knowing what the key will be for the particular output that I need |
Would something like “cdk deploy —format=json” which will output a json key value map of outputs and their values work? |
I am finding this quite difficult as well. I am using cdk in a Jenkins pipeline. |
I think that would be a good place to start |
Another significant dimension to the problem is that the output keys are
auto generated so I don’t have a good way to know what they will be because
of the random portions. The CDK format=JSON needs some way to locate
outputs by construct name and attribute name because the auto generated key
name can not be known ahead of time
…On Wed, Jul 10, 2019 at 7:59 AM Cristian Raț ***@***.***> wrote:
Would something like “cdk deploy —format=json” which will output a json
key value map of outputs and their values work?
I think that would be a good place to start
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1773>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AA2VN6U3MF2RZGFUGSWCMVTP6XFJPANCNFSM4GXSHCHQ>
.
|
For me simply selecting one of the outputs is enough. For example I need the
VPC id to for the next step of the Jenkins pipeline. So if I could do
cdk deploy...... --get-output MYID
Where MYID is what I specified as CfnOutput in the stack.
Hope this makes sense. Writing from phone
…On Wed, 10 Jul 2019, 20:44 Nathan Peck, ***@***.***> wrote:
Another significant dimension to the problem is that the output keys are
auto generated so I don’t have a good way to know what they will be because
of the random portions. The CDK format=JSON needs some way to locate
outputs by construct name and attribute name because the auto generated key
name can not be known ahead of time
On Wed, Jul 10, 2019 at 7:59 AM Cristian Raț ***@***.***>
wrote:
> Would something like “cdk deploy —format=json” which will output a json
> key value map of outputs and their values work?
>
> I think that would be a good place to start
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <
#1773
>,
> or mute the thread
> <
https://github.com/notifications/unsubscribe-auth/AA2VN6U3MF2RZGFUGSWCMVTP6XFJPANCNFSM4GXSHCHQ
>
> .
>
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1773>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ALFYCRB5WYYWTNGPAWGRA3TP6Y3Z5ANCNFSM4GXSHCHQ>
.
|
I've got a workaround for this. Rather than trying to get the value from an automatically named output we can manually create our own output in the CDK app like this: import cdk = require('@aws-cdk/core');
// A manually named output
new cdk.CfnOutput(this, 'LoadBalancerDNS', {
value: ecsService.loadBalancer.loadBalancerDnsName
}); Then its possible to locate the value for that manually named output in the CloudFormation outputs like this:
This CLI command will give you the value for the output, which in this case is the DNS for a load balancer. In my use case I needed to get the DNS name in order to run automated tests against the deployment, so I was able to embed this command in my build script after the CDK deploy to get the url for the deployed environment |
Exactly what I did. But working around to get functionality that should already exist, is not ideal :) |
My 2 bits. From an automation perspective.
Or even dump them in Currently I do something like: Then grep the outputs section, awk for the thing I want. It works, but using jq or a native cdk command that knew how to parse the An output file(s) would be a great initial step to this path I think. |
It doesn't really make sense that outputs will be saved to |
I would like to add consideration for dynamic stack names in this feature. For integration tests we have dynamic stack names with a git branch appended. Being able to Something like |
thank you so much @nathanpeck for the idea, the CfnOutput is amazing. Literally can output anything I need in precise detail like this. @eladb |
I am also trying to get some outputs of the deployed CF stacks. Does anyone have any workaround solution to make it works? |
@shivlaks this needs to be highly prioritized in the CLI backlog |
Another thing that would be valuable to me is resolved SSM parameters, or even just stack parameters of the currently deployed stacks. Seeing these in a similar command as what we're discussing on this issue would be nice. If SSM params are resolved by Cloudformation, they show up in the parameters section of the stack, so seeing them on the CLI would also be nice. Maybe this ask could be it's own issue? If we get outputs first, turning all params into an output would be a decent stop gap. |
I'll second having |
Just ran into this myself. 👍 Will probably go with the manual |
A different design would have the CLI become a library that user code invokes to deploy a stack. Being aware of the object model, the deploy step could fill in all tokens. |
It's really sad to see this not being available out of the box (like Since this is a common need for me and the projects I'm working on, I created a temporary solution in terms of an utility script: https://github.com/Dzhuneyt/cdk-get-stack-output script. I hope you find it useful. Sample usage: Contributions welcome. |
picking this task up! |
@shivlaks is there an rfc for the feature? |
Harsh considering it's only been in GA since July last year. Thanks for the script link though, do you have any documentation for it? |
@jsdtaylor Yes, the README.md. It's very simple to use with 2 parameters only. |
@nathanpeck 's solution should be fixed like below for me ⭐ : new cdk.CfnOutput(this, 'OutputId', {
value: ...,
exportName: 'OutputExportName',
});
|
While this isn't directly related to the CLI, some 'syntactic sugar' for It would be kind of cool if any As a short contrived example: class FooStack extends cdk.Stack {
// ..snip..
new cdk.CfnOutput(this, 'Foo', { value: 'foo!' })
// ..snip..
}
const app = new cdk.App()
const fooStack = new FooStack(app, 'foo', {})
console.log(fooStack.outputs['Foo']) I know we can use https://docs.aws.amazon.com/cdk/latest/guide/constructs.html talks about using standard JS class properties to expose relevant details, which is workable, but then we end up having to both define the property as well as the |
feat(cli): write stack outputs to a file Write stack outputs from deployments into a file. A flag `--outputs-file` can be provided where stack outputs will be written in `json` format. Supports multi-stack and wild-card deployments where all the generated outputs from deployed stacks will be written to the outputs file. Closes #1773
Here's a fork from nathanpeck using jq. Hope it helps.
|
It would be super helpful if there were two additions to
We're currently trying to get CDK outputs into a GatsbyJS build which uses |
Something like what Amplify does would be terrific |
Depending on what you're doing, JQ's test command is one way to get around the randomness in CDK-generated keys. For example, to get the Kubernetes config command for an EKS cluster: :; aws cloudformation describe-stacks --stack-name "$name_of_stack" |
jq -r '.Stacks | .[] | .Outputs[] | select(.OutputKey | test(".*ConfigCommand.*")) | .OutputValue' |
bash
Updated context arn:aws:eks:aaa:bbb:cluster/ccc in /Users/nnn/.kube/config |
// cloudformation stack output lookup
// output names are based on CDK node hierarchy + random suffix
// we could use exported names but then we have to worry about collisions
export enum StackOutput {
MigrationScriptArn = "MigrationScriptMigrationScriptArn",
}
let _stackOutputs: Output[]
// retrieve a stack output value
// throws an exception if none found
export const getStackOutput = async ({
cloudFormationClient,
output,
stackName,
}: {
cloudFormationClient: CloudFormationClient
output: StackOutput
stackName: string
}): Promise<string> => {
if (_stackOutputs) return lookupOutput(_stackOutputs, output)
// describe stacks
const descStackCmd = new DescribeStacksCommand({ StackName: stackName })
const { Stacks } = await cloudFormationClient.send(descStackCmd)
if (Stacks?.length !== 1) throw new Error(`Found ${Stacks?.length || 0} stacks named ${stackName}`)
const stack = Stacks[0]!
// get outputs
_stackOutputs = stack.Outputs || []
// find nested stacks of stack and get their outputs too
if (stack.StackId) {
const nestedStacks = await getNestedStacks(cloudFormationClient, stack.StackId)
// push nested stack outputs
_stackOutputs.push(...nestedStacks.flatMap((s) => s.Outputs).filter((o): o is Output => !!o))
}
// search
return lookupOutput(_stackOutputs, output)
}
/**
* Describe all stacks that are a descendent of rootStackId.
*/
const getNestedStacks = async (cloudFormationClient: CloudFormationClient, rootStackId: string): Promise<Stack[]> => {
// get pages of stack summaries
const descNestedStacksPaginator = paginateListStacks({ client: cloudFormationClient, pageSize: 50 }, {})
// get a list of stack IDs that have rootStackId as the root
const nestedStacksToDescribe: DescribeStacksCommand[] = []
for await (const page of descNestedStacksPaginator) {
const nestedStacks = page.StackSummaries?.filter((ss) => ss.RootId == rootStackId)
if (!nestedStacks) continue
nestedStacksToDescribe.push(
...nestedStacks.map(
(ss) =>
new DescribeStacksCommand({
StackName: ss.StackName,
})
)
)
}
// describe nested stacks (simultaneously)
const stackDescribeRes = await Promise.all(nestedStacksToDescribe.map((desc) => cloudFormationClient.send(desc)))
return stackDescribeRes.flatMap((sd) => sd.Stacks).filter((s): s is Stack => !!s)
}
// expect to find name in stackOutputs
// raise exception if not found
const lookupOutput = (stackOutputs: Output[] | undefined, name: StackOutput): string => {
const value = findOutputIn(stackOutputs, name)
if (value === undefined)
throw new Error(`Failed to find stack output ${name} in ${stackOutputs?.map((o) => o.OutputKey)}`)
return value
}
const findOutputIn = (stackOutputs: Output[] | undefined, name: StackOutput): string | undefined => {
// look for an output that begins with this name
return stackOutputs?.find((o) => o.OutputKey?.startsWith(name))?.OutputValue
} |
Building on previous answers and barring corner cases where you have multiple output values where the hashes do matter (e.g. "A/B/C" and "A/BC") or the logical IDs are too long so that CDK uses node addresses, you can just trim off the hash suffixes using some jq magic: # eval $(
for stack in $(cdk ls 2> /dev/null); do
aws cloudformation describe-stacks \
--stack-name $stack \
--query "Stacks[].Outputs[]" \
--output json | \
jq --arg stack $stack -r '.[] |
"\($stack + .OutputKey[0:-8])=\(.OutputValue | @sh)"'
done
# ) If you're certain it's safe to |
You can now use |
After deploying the stack, there's no way in the CLI to go back and get outputs from the deployed stack with the CDK CLI. I expected something like "cdk metadata" to give me this information.
For example, the LoadBalancedFargateService construct outputs the DNS name of the load balancer. It will be useful to be able to query that output value for a CDK stack with the CDK CLI.
The text was updated successfully, but these errors were encountered: