Find all Lambda-Runtimes in all Accounts: Multi Account Query with steampipe and TASFKAS (the AWS service formerly known as SSO *)

You have got some mails from AWS: [Action Required] AWS Lambda end of support for Node.js 12 [Action Required] AWS Lambda end of support for Python 3.6 [Solution Required] Search all Lambdas in multiple accounts.

[Solution Found] Steampipe with AWS multi-account support. Multi-account management is like managing all the arms of a Kraken. I will show you a fast and straightforward solution for this. (* the new offical name is IAM Identity Center, but I think TASFKAS would also fit 😉)

Architecture multi-account query solution


(1) In the IAM Identity Center, we define a Permission Set, which includes a AWSPowerUserAccess managed policy.

(2) Your user is assigned to a AWS Managed Policy AWSPowerUserAccess in all accounts, which should be queried

(3) All accounts are referenced in AWS user profiles

(4) With aws-sso-util we login into SSO

(5) All profiles are configured for Steampipe

(6) Steampipe does multi-account queries with all AWS user profiles

Step 1 - Configure

Steampipe - query AWS with SQL

What is Steampipe? It is a solution to query your AWS account (and many more things) with SQL. The AWS Compliance Mod gives you a dashboard supporting “configuration, compliance and security controls or full compliance benchmarks”, including the “AWS Foundational Security Best Practices”. The data for the dashboard is queried with SQL.

The installation is straightforward and documented on the website: install Steampipe .

For a Mac, the actions are:

brew tap turbot/tap
brew install steampipe
steampipe -v

The output for steampipe -v should be sth like:

steampipe version 0.16.0

We need to install the AWS plugin:

steampipe plugin install aws

This translates AWS Resources to SQL data tables. After the general AWS access is provided by the AWS plugin, you may choose from different mods. For a quick overview, there is the aws insights mod. For this usecase we use another mod, the AWS Compliance Mod.

Steampipe Mod for AWS Compliance

You clone the repository and start steampipe within this directory. You can also reference the working directory with the parameter --workspace-chdir. To do this, we save the current working directory in MOD:

git clone
cd steampipe-mod-aws-compliance
export MOD=`pwd`

The next step is to configure multi-account authentication.

Configuring Multi-Account

You could just use static credentials. More elegant is the Single Sign on solution, because you do not use static credentials.

Installing aws-sso-util

For SSO on the cli, we use this tool:

GitHub - benkehoe/aws-sso-util: Smooth out the rough edges of AWS SSO (temporarily, until AWS makes it better).

With this tool you login to AWS-SSO. Then you can use AWS user profiles to access all accounts, which are configured in the IAM Identity Center.

Aws user profiles

Locally on your laptop, you configure AWS user profiles matching the SSO profiles

vi ~/.aws/config
[profile megaproaktiv_dev]
credential_process=aws-sso-util credential-process --profile  megaproaktiv_dev

This is an example config for a profile. You need the sso-id ${yourssoid}, it looks like “d-1234567890”, the name of the role, here “AWSPowerUserAccess” and the account number ${youraccountid}, which is a 12 digit number.

Please note: the AWS config file does not support variables, you have to replace them with real world values.

Examples can be found on github.


With this configured, you start with a sso login.

aws-sso-util login

Where d-1234567890is you sso-id.

In the browser you login with your sso credentials and approve the request.

With a simple command, you can check, whether the login and the configuration is ok:

aws sts get-caller-identity  --profile megaproaktiv_dev
    "UserId": "",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_AWSReadOnlyAccess_e92dcd3dfcd065e3/"

You should see:

  • The userid of a temporarily created user - a AccessKey beginning with “AROA”-, followed by your SSO email
  • The number of the account referenced in the AWS user profile
  • The arn of the role you have assumed

For an explanation of the unique ID prefixes like AROA or AIDA, see the AWS Documentation.

Check other profiles

aws sts get-caller-identity  --profile megaproaktiv_test
aws sts get-caller-identity  --profile megaproaktiv_prod

Congrats, authorization is done!

Steampipe config multi Account

Now the aws authentication is done, next step is to tell steampipe to use all of these profiles:

The main configuration is in ~/.steampipe/config/aws.spc

You define the general AWS connection and the aggregator for all accounts:

connection "aws" {
  plugin = "aws"

  regions = ["eu-central-1"]

connection "megaproaktiv" {
 type        = "aggregator"
 plugin      = "aws"
 connections = ["megaproaktiv_*"]

And one entry per account:

connection "megaproaktiv_prod" {
  plugin = "aws"
  regions = ["eu-central-1"]
  profile = "megaproaktiv-prod"

connection "megaproaktiv_test" {
  plugin = "aws"
  regions = ["eu-central-1"]
  profile = "megaproaktiv-test"

connection "megaproaktiv_dev" {
  plugin = "aws"
  regions = ["eu-central-1"]
  profile = "megaproaktiv-dev"

All this configuration has to be done only once. Then you can query!

Step 2 - Query with dashboard

Standard dashboard

Now start steampipe in the terminal where you did the sso-login:

steampipe dashboard --search-path-prefix megaproaktiv --workspace-chdir ${MOD}

This will start your standard browser:

Dashboard Start

And give some logs in the terminal:

[ Wait    ] Loading Workspace
[ Wait    ] Starting Dashboard Server
[ Message ] Workspace loaded
[ Message ] Initialization complete
[ Ready   ] Dashboard server started on 9194 and listening on local
[ Message ] Visit http://localhost:9194
[ Message ] Press Ctrl+C to exit
[ Wait    ] Dashboard execution started: aws_compliance.benchmark.foundational_security

Now click on “AWS Foundational Security Best Practices ComplianceAWSBenchmark” in the browser and wait for Ready in the terminal. This will only take seconds!

[ Ready   ] Execution complete: aws_compliance.benchmark.foundational_security

After that you have to refresh the browser page once and you get the AWS Foundational Security Best Practices overview:


Scroll to lambda and klick “2 Lambda functions should use latest runtimes”.

You get a full multi-account list of all your lambdas. The accounts are blurred in the picture because of security.


(1) The name of the control

(2) The name of the Lambda functions

(3) region and account number

Oh, it warns about “Python 3.9”, thats wrong! Python 3.9 is a current Lambda runtime. That is because the foundational_security can’t keep up with all these changes. No problem, just update the SQL!

Change the query

In the steampipe-mod-aws-compliancedirectory, you see the query for the dashboard

vi query/lambda/lambda_function_use_latest_runtime.sql
  -- Required Columns
  arn as resource,
    when package_type <> 'Zip' then 'skip'
    when runtime in ('nodejs14.x', 'nodejs12.x', 'nodejs10.x', 'python3.8', 'python3.7', 'python3.6', 'ruby2.5', 'ruby2.7', 'java11', 'java8', 'go1.x', 'dotnetcore2.1', 'dotnetcore3.1') then 'ok'
    else 'alarm'
  end as status,
    when package_type <> 'Zip' then title || ' package type is ' || package_type || '.'
    when runtime in ('nodejs14.x', 'nodejs12.x', 'nodejs10.x', 'python3.8', 'python3.7', 'python3.6', 'ruby2.5', 'ruby2.7', 'java11', 'java8', 'go1.x', 'dotnetcore2.1', 'dotnetcore3.1') then title || ' uses latest runtime - ' || runtime || '.'
    else title || ' uses ' || runtime || ' which is not the latest version.'
  end as reason,
  -- Additional Dimensions

Now I am saying, only the newest runtimes of my favourite languages are allowed. See line 6:

    when runtime in ('nodejs14.x', 'nodejs12.x', 'nodejs10.x', 'python3.8', 'python3.7', 'python3.6', 'ruby2.5', 'ruby2.7', 'java11', 'java8', 'go1.x', 'dotnetcore2.1', 'dotnetcore3.1') then 'ok'

Change to

    when runtime in ('nodejs16.x',  'python3.9',  'ruby2.7',  'go1.x', 'java11') then 'ok'

And change in line 11 also:

    when runtime in ('nodejs14.x', 'nodejs12.x', 'nodejs10.x', 'python3.8', 'python3.7', 'python3.6', 'ruby2.5', 'ruby2.7', 'java11', 'java8', 'go1.x', 'dotnetcore2.1', 'dotnetcore3.1') then 


    when runtime in ('nodejs16.x',  'python3.9',  'ruby2.7',  'go1.x', 'java11') then title || ' uses latest runtime - ' || runtime || '.'

So the whole query/lambda/lambda_function_use_latest_runtime.sql query now looks like:

  -- Required Columns
  arn as resource,
    when package_type <> 'Zip' then 'skip'
    when runtime in ('nodejs16.x',  'python3.9',  'ruby2.7',  'go1.x', 'java11') then 'ok'
    else 'alarm'
  end as status,
    when package_type <> 'Zip' then title || ' package type is ' || package_type || '.'
    when runtime in ('nodejs16.x',  'python3.9',  'ruby2.7',  'go1.x', 'java11') then title || ' uses latest runtime - ' || runtime || '.'
    else title || ' uses ' || runtime || ' which is not the latest version.'
  end as reason,
  -- Additional Dimensions

You can find the SQL file on github.

Steampipe noticed the changed query file and execute the querys again.

Wait for another execution in the terminal:

[ Wait    ] Dashboard execution started: aws_compliance.benchmark.foundational_security
[ Ready   ] Execution complete: aws_compliance.benchmark.foundational_security

In the updated browser windows you see all lambdas, multi-account.

Now the is ok:

Compare Py

More to play

For some IAM controls of the dashboard “AWS Foundational Security Best Practices” you need AWS IAM credential reports.

If you klick on “5 MFA should be enabled for all IAM users that have a console password” without the credential report, you get an error:

...rpc error: code = Unknown desc = Credential report not available...

Credential Reports

Call the report generation with the profile names:

aws iam generate-credential-report --profile megaproaktiv_dev
aws iam generate-credential-report --profile megaproaktiv_prod
aws iam generate-credential-report --profile megaproaktiv_test


    "State": "STARTED",
    "Description": "No report exists. Starting a new report generation task"


    "State": "COMPLETE"

Usually takes only seconds

Even more to play

Least Privileges

I started with AWSPowerUserAccess permission set. That is not least privileges. Creating least privileges IAM policies is hard, but there is a trick:

iamlive to the rescue.

With iamlive you can generate a IAM policy from real world AWS api calls:

In another cli windows, start:

iamlive --set-ini --mode proxy --sort-alphabetical --force-wildcard-resource --output-file policy.json

In the windows where you start the dashboard do:

export HTTP_PROXY=
ca_bundle = ~/.iamlive/ca.pem

Then start the dashboard again.

This will take a few minutes, but you end up with a nice least privileges policy in the file policy.json.

You will find an example of the new policy on github.


Fast ad-hoc Multi-Account queries of AWS resources can be done with steampipe. Once you get the configuration right, you can work with dashboards or html exports or junit export etc. For me this is an easy way to monitor AWS resources in addition to the AWS Configservice.

How to get no more Lambda end-of-support mails? Use go on aws, that is backward compatible and needs no runtime version updates.

For more AWS development stuff, follow me on twitter @megaproaktiv

See also

Thanks to

Photo by Swanson Chan on Unsplash

Similar Posts You Might Enjoy

New AWS Config Rules - LambdaLess and rust(y)

AWS Config checks all your resources for compliance. With 260 managed rules, it covers a lot of ground. But if you need additional checks until now, you had to write a complex Lambda function. With the new “Custom Policy” type, it is possible to use declarative Guard rules. Custom Policy rules use less lines of code and are so much easier to read. - by Gernot Glawe

About Optimizing for Speed: How to do complete AWS Security&Compliance Scans in 5 minutes

The project steampipe uses a fast programing language and an intelligent caching approach outrunning prowler speed tenfold. While I tried to workaround prowlers limits I learned a lot about optimizing. - by Gernot Glawe

(Prevent) Hacking into a CloudService - About security, ECS and terraform AWS UserGroup Hannover Online Meetup Feb, 4th 2021

Yoni: Oftentimes, when we think about protecting resources in the cloud, we immediately think about the typical ways in - via public-facing applications or abuse of credentials. In this talk, we will look at one additional way: through the work unit parameters of a service. During the development of Indeni’s Cloudrail SaaS product, Yoni was responsible for trying to find ways to hack into the service. One of the ways he found, raises questions about how secure ECS workloads really are. - by Yoni Leitersdorf , Gernot Glawe , Malte Walkowiak