Setting up an AWS Integration
CloudQuery Platform authenticates with AWS through cross-account IAM roles using IAM Roles for Service Accounts (IRSA). This guide walks through the manual setup process. Use this if your organization manages IAM roles through infrastructure-as-code (Terraform, CDK) or restricts CloudFormation usage. For an automated approach using CloudFormation, see the AWS Onboarding Wizard.
The AWS accounts involved are:
- CloudQuery Account: The AWS account where CloudQuery Platform is deployed. This account hosts the IAM role that CloudQuery uses to assume roles in other accounts.
- Your Account: The AWS account you want to sync resources from. You create a role here that allows the CloudQuery account’s role to assume it and read resources.
Prerequisites
- A CloudQuery Platform account with admin access
- AWS CLI installed and configured with credentials that have IAM administrative permissions
- Your AWS account ID
EXTERNAL_ID: Generate this yourself (e.g., by runninguuidgen). An external ID is recommended by AWS best practices to provide an additional verification layer when assuming roles in a third-party account. It can be any alphanumeric string between 2 and 1224 characters.
Step 1: Select configuration mode
- Navigate to Data Pipelines → Integrations.
- Click Create Integration and select AWS.
- Choose how to configure what CloudQuery syncs from your AWS account.

- All features: enables all three features automatically — Asset Inventory, Cost Metrics, and Additional Metadata. Recommended for most users.
- Individual features: lets you choose which features to enable from the list below.
- Manual services and tables configuration: lets you select individual AWS services or specific tables to sync. Does not set up Cost Metrics.
If you selected Individual features, choose from the following:
| Feature | What it syncs | Sync created |
|---|---|---|
| Asset Inventory | 301 core AWS resource tables (EC2, IAM, RDS, S3, Lambda, etc.) plus CloudTrail write events | Two syncs: {integration name} - Asset Inventory and {integration name} - CloudTrail |
| Cost Metrics | AWS Cost and Usage Report (CUR 2.0) data via BCM Data Exports | One sync: {integration name} - Cost and Usage using the cloudquery/awscur plugin |
| Additional Metadata | 68 supplementary tables for snapshots, policies, attachments, and account credentials — used by Reports and Insights | One sync: {integration name} - Additional Metadata |
If you selected Manual services and tables configuration, choose the AWS services or individual tables you want to sync. Cost Metrics are not available in this mode.
All features is recommended for most users. It enables the Asset Inventory view, cost analysis, and all Reports and Insights functionality out of the box.
Step 2: Choose authentication method and account scope
Select Manual authentication method. This will allow you to provide your own IAM role ARNs.

IAM role and permissions
Deploy the read-only role and Cost & Usage export with one CloudFormation stack instead of running the commands in the other tab. The stack creates a role that trusts the role used by CloudQuery.
Replace the <EXTERNAL_ID> in the command below with a value you generate (e.g. uuidgen).
Replace the <CLOUDQUERY_ROLE_ARN> with the role ARN displayed in the side panel documentation on the integration UI page in CloudQuery Platform.
aws s3 cp s3://cq-cloud-cloudformation-templates-us-east-1/onboarding/unified/self-service-template.json self-service-template.json && \
aws cloudformation deploy \
--stack-name cloudquery-readonly \
--template-file self-service-template.json \
--capabilities CAPABILITY_NAMED_IAM \
--region us-east-1 \
--parameter-overrides \
CloudQueryRoleArn=<CLOUDQUERY_ROLE_ARN> \
ExternalId=<EXTERNAL_ID> \
EnableAssetInventory=true \
EnableCostAndUsage=trueWhen the stack reaches CREATE_COMPLETE, read its outputs:
aws cloudformation describe-stacks \
--stack-name cloudquery-readonly \
--region us-east-1 \
--query "Stacks[0].Outputs" --output tableCopy RoleArn and CurReportName from the outputs into the Role ARN and CUR report name fields, and enter the same External ID you used in the command. Cost & Usage is single-account, so deploy the stack in that one account only.
-
Click Test and Continue to verify the setup.
-
Specify the schedule and destination
You can specify how often the integration data gets refreshed from the cloud provider. We recommend scheduling syncs to run daily to keep your asset inventory and insights up to date.
If you choose to sync to an external destination (other than CloudQuery), the synced data will not be visible in CloudQuery directly.
Review your selected configuration and click Create to finalize. CloudQuery will start syncing the data.
What gets synced
The AWS integration can sync over 500 tables across all major AWS services. Some of the most commonly used tables include:
| Category | Tables | Description |
|---|---|---|
| Compute | aws_ec2_instances, aws_lambda_functions | EC2 instances, Lambda functions |
| Storage | aws_s3_buckets, aws_ebs_volumes | S3 buckets, EBS volumes |
| Networking | aws_ec2_vpcs, aws_ec2_security_groups, aws_ec2_subnets | VPCs, security groups, subnets |
| Identity | aws_iam_roles, aws_iam_users, aws_iam_policies | IAM roles, users, policies |
| Databases | aws_rds_instances, aws_rds_clusters | RDS instances and clusters |
See the full AWS table list for all available tables.
Verify the integration
After your first syncs complete, browse your AWS resources in the Asset Inventory under the Compute, Storage, Identity, and other categories.
You can also open the SQL Console and run these queries to confirm data arrived:
-- Count synced EC2 instances
SELECT count(*) FROM aws_ec2_instances-- List synced AWS accounts and regions
SELECT DISTINCT account_id, region FROM aws_ec2_instances-- View S3 buckets across accounts
SELECT account_id, name, region FROM aws_s3_buckets LIMIT 10Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
AccessDenied when assuming role | Trust relationship misconfigured | Verify the Principal ARN in the trust policy matches the CloudQuery account role exactly. Check that <CLOUDQUERY_AWS_ACCOUNT_ID> and <TENANT_ID> are correct. |
| External ID mismatch | EXTERNAL_ID in trust policy differs from the secret | Ensure the EXTERNAL_ID value in the IAM trust policy matches the secret value in CloudQuery Platform exactly |
InvalidIdentityToken | IRSA configuration issue | Verify the CloudQuery Platform deployment has a valid OIDC provider. See AWS IRSA documentation. |
| No data after sync | Tables list is empty or incorrect | In the YAML configuration, check the tables field. Use ["*"] to sync everything, or specify individual table names from the AWS tables list. |
| Partial data (missing accounts) | Member roles not deployed | For multi-account setups, verify the CloudFormation StackSet deployed roles to all target accounts. Run aws cloudformation describe-stacks to check. |
Next steps
- Set up a sync to schedule when your AWS data is fetched
- Browse synced resources in the Asset Inventory
- Run advanced queries in the SQL Console
- See the AWS integration documentation for full configuration options and table reference
Related resources
- AWS IAM cross-account access: AWS documentation on external ID best practices
- AWS ReadOnlyAccess policy reference: full list of permissions granted
- AWS CLI installation guide
- AWS STS AssumeRole: API reference for role assumption
- CloudQuery AWS integration on Hub: full integration documentation
Last updated on