{"id":21016577,"url":"https://github.com/gsa/grace-inventory","last_synced_at":"2025-10-05T21:44:43.993Z","repository":{"id":47535800,"uuid":"209330278","full_name":"GSA/grace-inventory","owner":"GSA","description":"Lambda function to create an inventory report of AWS services as an Excel spreadsheet in an S3 bucket. Includes Terraform code to deploy it.","archived":false,"fork":false,"pushed_at":"2023-10-13T17:20:26.000Z","size":302,"stargazers_count":14,"open_issues_count":7,"forks_count":10,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-05-15T05:35:18.143Z","etag":null,"topics":["grace"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GSA.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-18T14:33:06.000Z","updated_at":"2023-07-31T20:11:53.000Z","dependencies_parsed_at":"2024-06-19T01:32:29.974Z","dependency_job_id":"ad29bb0e-2e18-4871-9632-c880f1d06349","html_url":"https://github.com/GSA/grace-inventory","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":"GSA/grace-template","purl":"pkg:github/GSA/grace-inventory","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GSA%2Fgrace-inventory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GSA%2Fgrace-inventory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GSA%2Fgrace-inventory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GSA%2Fgrace-inventory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GSA","download_url":"https://codeload.github.com/GSA/grace-inventory/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GSA%2Fgrace-inventory/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278526241,"owners_count":26001325,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["grace"],"created_at":"2024-11-19T10:14:33.795Z","updated_at":"2025-10-05T21:44:43.966Z","avatar_url":"https://github.com/GSA.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003ca name=\"top\"\u003eGRACE Inventory Lambda Function\u003c/a\u003e [![GoDoc](https://godoc.org/github.com/GSA/grace-inventory?status.svg)](https://godoc.org/github.com/GSA/grace-circleci-builder) [![Go Report Card](https://goreportcard.com/badge/gojp/goreportcard)](https://goreportcard.com/report/github.com/GSA/grace-inventory)\n\n**Lint Checks/Unit Tests:** [![CircleCI](https://circleci.com/gh/GSA/grace-inventory.svg?style=shield)](https://circleci.com/gh/GSA/grace-inventory)\n\n**Integration Tests:** [![CircleCI](https://circleci.com/gh/GSA/grace-inventory-tests.svg?style=shield\u0026circle-token=f86712ce5167665fe0d4a23d4af4fe7e9a20f7de)](https://circleci.com/gh/GSA/grace-inventory-tests)\n\nLambda function to create an inventory report of AWS services as an Excel\nspreadsheet in an S3 bucket. Includes Terraform code to deploy the Lambda\nfunction and create S3 bucket and necessary IAM roles/permissions. The Lambda\nfunction can inventory all accounts in an AWS organization, specified\norganizational units, a specified list of AWS accounts or simply services in the\naccount the Lambda function is installed in.\n\n## Table of Contents\n\n- [Security Compliance](#security-compliance)\n- [Inventoried Services](#inventoried-services)\n- [Repository contents](#repository-contents)\n- [Usage](#usage)\n    - [Download](#download)\n    - [Build/Compile Locally](#buildcompile-locally)\n        - [Prerequisites](#prerequisites)\n        - [Build](#build)\n    - [Example Usage](#example-usage)\n    - [Intermittent Error](#intermittent-error)\n- [Terraform Module Inputs](#terraform-module-inputs)\n- [Terraform Module Outputs](#terraform-module-outputs)\n- [Environment Variables](#environment-variables)\n    - [CircleCI Environment Variables](#circleci-environment-variables)\n    - [Lambda Function Environment Variables](#lambda-function-environment-variables)\n- [Public domain](#public-domain)\n\n[top](#top)\n\n## Security Compliance\n\n**Component ATO status:** draft\n\n**Relevant controls:**\n\nControl    | CSP/AWS | HOST/OS | App/DB | How is it implemented?\n---------- | ------- | ------- | ------ | ----------------------\n[CM-8](https://nvd.nist.gov/800-53/Rev4/control/CM-8) | ╳ | | | Employs an automated Lambda function triggered by a scheduled CloudWatch event (every 24 hours, by default).  Inventories supported services in specified AWS accounts and stores results in an Excel Spreadsheet on an S3 bucket.\n[CM-8(2)](https://nvd.nist.gov/800-53/Rev4/control/CM-8) | ╳ | | | Automated by scheduled CloudWatch event (every 24 hours, by default).  Can be triggered more often to maintain an up-to-date, complete, accurate and readily available inventory of the AWS cloud service components.\n\n[top](#top)\n\n## Supported Services\n\n    - Organization Accounts\n    - IAM Roles\n    - IAM Groups\n    - IAM Policies\n    - IAM Users\n    - S3 Buckets\n    - Glacier Vaults\n    - EC2 Instances\n    - EC2 Internet Gateways\n    - Amazon Machine Images (AMI)\n    - EBS Volumes\n    - Snapshots\n    - VPCs\n    - Subnets\n    - Security Groups\n    - IP Addresses\n    - Key Pairs\n    - Elastic Load Balancers (elbv2)\n    - CloudFormation Stacks\n    - CloudWatch Alarms\n    - Config Service Rules\n    - KMS Keys\n    - RDS Instances and Snapshots\n    - Secrets Manager Secrets\n    - SNS Subscriptions and Topics\n    - SSM Parameter Stores\n\n[top](#top)\n\n## Repository contents\n\n- **./**: Terraform module to deploy and configure Lambda function, S3 Bucket and IAM roles and policies\n- **handler**: Go code for Lambda function\n- **examples**: Examples of how to use the terraform module\n- **tests**: Root module for testing deployment of Lambda function\n\n[top](#top)\n\n## Usage\n\nTo use the Terraform module to deploy the lambda function, you will need to either\ndownload the binary release from Github or compile the handler locally.\n\n[top](#top)\n\n### Download (Recommended)\n\n```bash\nmkdir -p release\ncd release\ncurl -L https://github.com/GSA/grace-inventory/releases/download/v0.1.3/grace-inventory-lambda.zip -o grace-inventory-lambda.zip\ncd ..\n```\n\n[top](#top)\n\n### Build/Compile Locally (Not Recommended)\n\n#### Prerequisites\n\n- Install the following prerequisites:\n    1. [Go](https://golang.org/)\n    1. [GolangCI-Lint](https://github.com/golangci/golangci-lint)\n    1. [gosec](https://github.com/securego/gosec)\n    1. [make](https://www.gnu.org/software/make/)\n\n[top](#top)\n\n#### Build\n\n- After installing all required prerequisites: compile the lambda function and\nput it in a zip compressed archive in `./release/grace-inventory-lambda.zip` by\nentering the following at a command prompt:\n\n```bash\nmake build_handler\n```\n\n#### Alternative Build (Not Recommended)\n\nIf your IAM permissions prevent the tests from succeeding, you can build manually:\n\n```bash\nmkdir -p release\ncd handler\nGOOS=linux GOARCH=amd64 go build -o ../release/grace-inventory-lambda -v\ncd ../release\nzip -j grace-inventory-lambda.zip grace-inventory-lambda\nrm grace-inventory-lambda\ncd ..\n```\n\n[top](#top)\n\n### Example Usage\n\nTo inventory a single AWS account to which the Lambda function is deployed,\ninclude the following in your root terraform module:\n\n```\nmodule \"example_self\" {\n  source       = \"github.com/GSA/grace-inventory?ref=v0.1.3\"\n  source_file  = \"../../release/grace-inventory-lambda.zip\"\n  appenv       = \"environment\"\n  project_name = \"your-project\"\n}\n```\n\nEnsure the `source_file` parameter is the path to the zip archive containing\nthe compiled Lambda function handler downloaded or compiled earlier.\n\n\nSee the [examples](examples) directory for more examples.\n\n**Note:** The S3 bucket created to store the inventory spreadsheets has logging\nenabled and requires a pre-existing bucket with a name in the form of:\n`${var.project_name}-${var.appenv}-access-logs`. The LogDelivery group must have\nWRITE and READ_ACP permissions on the bucket (`acl = \"log-delivery-write\"`).\nIf your logging bucket has a different name or does not exist, you will have to\ncreate one or fork this repository and edit the logging configuration of the S3\nbucket on\n[Line 10 of `iam.tf`](https://github.com/GSA/grace-inventory/blob/9b46d0bfbf40d6b9a5237afb9a45621a2f1a85d9/s3.tf#L10)\n\n**Note:** The `DEFAULT_REGION` for the lambda function to write to the S3 Bucket\nwill be the first region listed in the `regions` attribute.  By default, this is\n`us-east-1`.  If you want to place the S3 bucket in a different region, then you\nwill need to set the `regions` attribute with your desired region first in the\ncomma delimited list.\n\n### Intermittent Error\n\nThe KMS key policy depends on the IAM role, however, even though Terraform creates\nthe IAM role first, there is sometimes a delay in the configuration reaching\neventual consistency within AWS. This can result in the following error:\n\n```\nError: MalformedPolicyDocumentException: Policy contains a statement with one or more invalid principals.\n\tstatus code: 400, request id: 2425f0db-3033-448c-8e20-347eec8cac03\n\n  on .terraform/modules/example_self/kms.tf line 1, in resource \"aws_kms_key\" \"kms_key\":\n   1: resource \"aws_kms_key\" \"kms_key\" {\n```\n\nRe-applying the terraform (`terraform apply`) will usually resolve the problem.\nTerraform considers this a retriable error, so you can also increase the\n`max_retries` in the aws provider:\n\n```\nprovider \"aws\" {\n  max_retries = 5\n}\n```\n\n[top](#top)\n\n## Terraform Module Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|:----:|:-----:|:-----:|\n| source\\_file | \\(optional\\) full or relative path to zipped binary of lambda handler | string | `\"../release/grace-inventory-lambda.zip\"` | no |\n| appenv | \\(optional\\) The environment in which the script is running \\(development \\| test \\| production\\) | string | `\"development\"` | no |\n| project_name | \\(required\\) project name \\(e.g. grace, fcs, fas, etc.\\). Used as prefix for AWS S3 bucket name | string | `\"grace\"` | yes |\n| access\\_logging\\_bucket | \\(optional\\) the S3 bucket that will receiving on-access logs for the inventory bucket | string | `\"\"` | no |\n| accounts\\_info | \\(optional\\) Determines which accounts to parse.  Can be \"self\", comma delimited list of Account IDs or an S3 URI containing JSON output of `aws organizations list-accounts`.  If empty, tries to query accounts with `organizations:ListAccounts` | string | `\"self\"` | no |\n| master\\_account\\_id | \\(optional\\) Account ID of AWS Master Payer Account | string | `\"\"` | no |\n| master\\_role\\_name | \\(optional\\) Role assumed by lambda function to query organizations in Master Payer account | string | `\"\"` | no |\n| organizational\\_units | \\(optional\\) comma delimited list of organizational units to query for accounts. If set it will only query accounts in those organizational units | string | `\"\"` | no |\n| regions | \\(optional\\) Comma delimited list of AWS regions to inventory.  **Note:** The first region listed will be used by the lambda function as the `DEFAULT_REGION`. | string | `\"us-east-1,us-east-2,us-west-1,us-west-2\"` | no |\n| schedule\\_expression | \\(optional\\) Cloudwatch schedule expression for when to run inventory | string | `\"cron(5 3 ? * MON-FRI *)\"` | no |\n| tenant\\_role\\_name | \\(optional\\) Role assumed by lambda function to query tenant accounts | string | `\"OrganizationAccountAccessRole\"` | no |\n| lambda_memory | \\(optional\\) The number of megabytes of RAM for the lambda | number | 2048 | no |\n| sheets | \\(optional\\) A comma delimited list of sheets | string | `\"\"` | no |\n\n[top](#top)\n\n## Terraform Module Outputs\n\n| Name | Description |\n|------|-------------|\n| lambda\\_function\\_arn | The Amazon Resource Name \\(ARN\\) identifying the Lambda Function |\n| lambda\\_function\\_kms\\_key\\_arn | The ARN for the KMS encryption key |\n| lambda\\_function\\_last\\_modified | The date this resource was last modified |\n| s3\\_bucket\\_id | The name of the S3 bucket where inventory reports are saved |\n\n[top](#top)\n\n## Environment Variables\n\n### Lambda Function Environment Variables\n\n| Name                 | Description |\n| -------------------- | ------------|\n| s3_bucket            | (required) S3 Bucket to store inventory reports |\n| kms_key_id           | (required) ID of KMS key for encrypting/decrypting S3 bucket objects |\n| regions              | (required) comma delimited list of regions to be inventoried |\n| accounts_info        | (optional) If `accounts_info` is empty or not set, the function will try to query accounts via the Organizations API.  If set to \"self\", then it will only inventory its own account.  If set to an S3 URI for a file containing the json output of the `aws organizations list-accounts` command, it will query all accounts listed.  If set to a comma separated list of account IDs, it will query those accounts. |\n| master_account       | (optional) Account ID of master payer account |\n| organizational_units | (optional) comma delimited list of organizational units to query for accounts. If set it will only query accounts in those organizational units |\n| tenant_role_name            | (optional) Role name used to inventory tenant accounts |\n| master_role_name            | (optional) Role name to assume in master payer account for querying organizations |\n| sheets | (optional) A comma delimited list of sheets that should be generated (see [sheets](#sheets))\n\n[top](#top)\n\n## Sheets\n\n| Name | Permission | Description |\n| ---- | ---------- | ----------- |\n| Roles | iam:ListRoles | queries IAM Roles |\n| Groups | iam:ListGroups | queries IAM Groups |\n| Policies | iam:ListPolicies | queries IAM Policies |\n| Users | iam:ListUsers | queries IAM Users |\n| Buckets | s3:ListBuckets | queries S3 Buckets |\n| Instances | ec2:DescribeInstances | queries EC2 Instances |\n| Images | ec2:DescribeImages | queries EC2 Images |\n| Volumes | ec2:DescribeVolumes | queries EC2 Volumes |\n| Snapshots | ec2:DescribeSnapshots | queries EC2 Snapshots |\n| IGWs | ec2:DescribeInternetGatewaysPages | queries EC2 IGWs |\n| VPCs | ec2:DescribeVpcs | queries EC2 VPCs |\n| VpcPeers | ec2:DescribeVpcPeeringConnectionsPages | queries EC2 Vpc Peers |\n| Subnets | ec2:DescribeSubnets | queries EC2 Subnets |\n| SecurityGroups | ec2:DescribeSecurityGroups | queries EC2 Security Groups |\n| Addresses | ec2:DescribeAddresses | queries EC2 Addresses |\n| KeyPairs | ec2:DescribeKeyPairs | queries EC2 Key Pairs |\n| Stacks | cloudformation:DescribeStacks | queries Cloud Formation Stacks |\n| Alarms | cloudwatch:DescribeAlarms | queries CloudWatch Alarms |\n| ConfigRules | config:DescribeConfig | queries AWS Config rules |\n| LoadBlancers | elasticloadbalancing:DescribeLoadBalancers | queries Elastic Load Balancers |\n| Vaults | glacier:ListVaults | queries Glacier Vaults |\n| Keys | kms:ListKeys | queries KMS Keys |\n| DBInstances | rds:DescribeDBInstances | queries RDS Database Instances |\n| DBSnapshots | rds:DescribeDBSnapshots | queries RDS Database Snapshots |\n| Secrets | secretsmanager:ListSecrets | queries Secrets Manager secrets |\n| Subscriptions | sns:ListSubscriptions | queries Simple Notification Service Subscriptions |\n| Topics | sns:ListTopics | queries Simple Notification Service Topics |\n| Parameters | ssm:DescribeParameters | queries AWS Systems Manager Parameters |\n\n## Public domain\n\nThis project is in the worldwide [public domain](LICENSE.md). As stated in [CONTRIBUTING](CONTRIBUTING.md):\n\n\u003e This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/).\n\u003e\n\u003e All contributions to this project will be released under the CC0 dedication. By submitting a pull request, you are agreeing to comply with this waiver of copyright interest.\n\n[top](#top)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgsa%2Fgrace-inventory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgsa%2Fgrace-inventory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgsa%2Fgrace-inventory/lists"}