-- Leo's gemini proxy

-- Connecting to capsule.adrianhesketh.com:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini; charset=utf-8

capsule.adrianhesketh.com


home


Export all CloudFormation templates for a pentest


Prior to the first release of a project, alongside internal security testing, and security tooling carried out as part of CI/CD, it's common to have a pentest carried out by a 3rd party security team to check over everything.


Security teams often request the CloudFormation templates used to create infrastructure, since having good documentation gives them the best chance to find issues.


In my latest project, there are 21 CDK projects that make up the overall solution, so when I was asked, my first thought was to check out each of the projects, and run the `cdk synth` to export the raw CloudFormation, but that would take a relatively long time, so I picked up the AWS CLI instead.


Just tell me how to do it


Install jq


https://github.com/stedolan/jq


Create `run.sh`


aws cloudformation list-stacks --output=json | jq --raw-output '.StackSummaries | map(.StackName) | .[]' | xargs -L 1 ./get.sh

Create `get.sh`


Create a `get.sh` file with the following contents.


aws cloudformation get-template --output=json --stack-name=$1 | jq --raw-output ".TemplateBody | ." > $1.yaml

Run it


Log in to your AWS account on the command line, and run `./run.sh`.


How does it work?


Getting the template for a single stack


The AWS CLI allows us to get a single stack contents but doesn't output the raw template contents, so the output needs to be tidied up.


aws cloudformation get-template --output=json --stack-name=myteststack`

Outputting JSON enables the output to be piped into the `jq` command line tool [0] which can execute filter and transform operations on JSON to extract just the required information.


[0]


I have my CLI set to output JSON by default [1] to enable scripting, but you can add the `--output=json` flag to any AWS CLI command to force it.


[1]


`jq` can filter the result to only output the contents of the `TemplateBody` field and produce plain text output (using the `--raw-output` parameter).


The built-in shell operator `>` can write the output to a file.


Adding the command to a `get.sh` file, provides a resuable script that takes a positional parameter (`$1`) for the stack name, e.g. `./get.sh mytesttemplate`:


aws cloudformation get-template --output=json --stack-name=$1 | jq --raw-output ".TemplateBody | ." > $1.yaml

Listing all CloudFormation stacks


Listing the stacks is straightforward.


aws cloudformation list-stacks --output=json

But as per the docs [1], the output looks something like this:


{
  "StackSummaries": [
    {
        "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896",
        "TemplateDescription": "AWS CloudFormation Sample Template S3_Bucket: Sample template showing how to create a publicly accessible S3 bucket. **WARNING** This template creates an S3 bucket. You will be billed for the AWS resources used if you create a stack from this template.",
        "StackStatusReason": null,
        "CreationTime": "2013-08-26T03:27:10.190Z",
        "StackName": "myteststack",
        "StackStatus": "CREATE_COMPLETE"
    }
  ]
}

[1]


Since only the stack name is required, `jq` can be used to filter the output and output all the stack names, one on each line.


aws cloudformation list-stacks --output json | jq --raw-output '.StackSummaries | map(.StackName) | .[]'

Breaking down the `jq` parameters:


`'.StackSummaries | map(.StackName)'` gets the contents of the `StackSummaries` field, and then extracts the value of each `StackName` field into an output array.

`.[]` outputs the array.

`--raw-output` means that `jq` outputs plain text instead of JSON.


The output looks something like this:


myteststack
stack2

Connecting up with xargs


To execute the `./get.sh` script for every stack, the output of the `list-stacks` command gets piped into the `xargs` command.


The `-L 1` parameter of `xargs` tells `xargs` that each line of the input should be used to execute the `./get.sh` script with the contents of the input line as a parameter.


aws cloudformation list-stacks| jq --raw-output '.StackSummaries | map(.StackName) | .[]' | xargs -L 1 ./get.sh

More


Next


Verifying download hashes during Docker build


Previous


Using AWS API Gateway V2 with Go Lambda functions


Home


home

-- Response ended

-- Page fetched on Sat Apr 27 19:13:30 2024