This folder contains a program called generate-securityhub which is used to manage the aws-securityhub
module in this repo. The code generator is used to make it easier to manage terraform blocks
that need to apply to more than one region.
Installation
generate-securityhub is a single, self-contained, statically compiled binary written in Go. The easiest way to get it onto your servers is to use the Gruntwork
Installer (make sure to replace <VERSION> below with the latest
version from the releases page):
Alternatively, you can download the binary from the Releases
Page.
Usage
This command should be run in the modules folder of this repo. This command will output the autogenerated contents of
the aws-securityhub module that can be used to enable AWS Security Hub on all enabled regions of an account.
Note that you can also use this command to generate the module in a different folder, such as your own
infrastructure-modules repo.
For example, suppose you had an infrastructure-modules repository that mimics the Gruntwork Reference Architecture,
and has the following structure:
Suppose that you now want to add a module aws-securityhub as generated by this script in the security folder. To do
so, first install the binary so that it is available in your PATH as described in the Installation section of this
docs.
Next, run the generator in the infrastructure-modules directory, passing in the target directory and main region. Note
that you will need to be authenticated to your AWS account. Refer to the Comprehensive Guide to Authenticating to AWS
on the Command
Line for
recommended ways to authenticate on the command line.
You can now invoke the module using Terragrunt, or any other production Terraform frontend that you are currently using.
Building the Binary
We use packr to compile the templates into the binary so that it is portable. To
do so, we need to run packr2 prior to building the binaries.
Here are the steps for compiling from source:
Install the packr2 binary: go get -u github.com/gobuffalo/packr/v2/packr2
Run $GOPATH/bin/packr2. This will convert the template files into go files so that they are available in the go
binary.
Mark gruntwork-io as private repos so that they are fetched with ssh: go env -w GOPRIVATE=github.com/gruntwork-io
Build the generate-securityhub binary: go build -o $BIN_PATH .
Working with the invite-external-accounts Python Script
Since terraform currently does not support managing Security Hub multi account memberships, we use python with the
boto3 library to workaround it. The script to handle the logic for managing multi account memberships is shipped with
the generated aws-securityhub module. The source code for the script lives in data/static/invite-external-accounts.
To support portability of the python libraries, we package all the dependencies of the scripts into a
pex file. This pex file must be distributed with the module in
order to be correctly called by terraform without the user having to install extra python dependencies into their
system.
As such, the operator machine consuming the module must have a valid python interpreter available in the PATH under
the name python. The pex binary supports python versions 2.7, 3.5, 3.6, and 3.7, on Mac OSX or Linux.
Building the binary
The pex binary is a python executable that includes the necessary third party requirements. This special version of python
embeds cross platform versions of the requirements that are unpacked at runtime into a
virtualenv. This executable is then used to call out to the entrypoint script,
which will import the library function.
As such, the binary only needs to be built when the requirements change. You do not need to rebuild the binary for any
changes to the source files in the invite_external_accounts library.
This approach is taken so that consumers of the module do not need to install additional third party libraries on top of
python to utilize the script. To make this work, the pex binaries need to be checked into the repository so that they
are distributed with the module.
The binary is generated using the pex utility. Pex will package
the python script with all its requirements into a single binary, that can be made to be compatible with multiple
versions of python and multiple OS platforms.
To build the binary, you will need the following:
A working python environment with all compatible versions of python setup (so that you can build binaries for all
versions)
You can then build the binary using the helper script build_scripts/build.sh which will build the binary and create a
tarball containing the binaries. This tarball should be checked in so that the generate-securityhub utility can
distribute it with the generated Terraform module.
It is recommended to use pyenv to help setup an environment with multiple python
interpreters. The latest binaries are built with the following python environment:
pyenv shell 2.7.153.5.23.6.63.7.0
Questions? Ask away.
We're here to talk about our services, answer any questions, give advice, or just to chat.
{"treedata":{"name":"root","toggled":true,"children":[{"name":".circleci","children":[{"name":"config.yml","path":".circleci/config.yml","sha":"f5221bddaff4eea1f0a9e6f623ea49e50cb00cbc"}]},{"name":".gitignore","path":".gitignore","sha":"03aff38511349fa3b4441e2b0157b707218aa7ef"},{"name":".pre-commit-config.yaml","path":".pre-commit-config.yaml","sha":"b9fd389c37a0872a9d838269b406c0f8186acfcc"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"47ca720c554dc4a85a502b796941512d019f6046"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","sha":"a4c2813ee9206bc483df5fec152369c60b89de98"},{"name":"LICENSE.txt","path":"LICENSE.txt","sha":"dbc5cd9a551f59b0f647602d3b5a62409a27ad75"},{"name":"README.adoc","path":"README.adoc","sha":"8f49d11b20cb2aeddf5ed21e14e7cbd3c8ee3df2"},{"name":"_docs","children":[{"name":"aws-cloudtrail.png","path":"_docs/aws-cloudtrail.png","sha":"c5482ed9b343509b76ce9678c5d6fcc07902a664"},{"name":"aws-cloudwatch.png","path":"_docs/aws-cloudwatch.png","sha":"5211cf11b76d724d86ffe022a314c443afef74cf"},{"name":"aws-config.png","path":"_docs/aws-config.png","sha":"bfa3bd7f86edfb2d914b2fad0c608b8120cb13cd"},{"name":"aws-iam.png","path":"_docs/aws-iam.png","sha":"9c0ebb4b5543199462b52282d86617db471ec48a"},{"name":"cis-account-architecture.png","path":"_docs/cis-account-architecture.png","sha":"86113f679c13fb529ceed5596fecec41d5204f54"},{"name":"cis-logo.png","path":"_docs/cis-logo.png","sha":"e75a052f28ac1e4d1d2292fa6cdc1ccd6a904885"}]},{"name":"codegen","children":[{"name":"generate-securityhub","children":[{"name":".gitignore","path":"codegen/generate-securityhub/.gitignore","sha":"61f44f130bdff8fcac8058495bd28ffd9062de25"},{"name":"README.md","path":"codegen/generate-securityhub/README.md","sha":"54c6a598c451f3618b7fdd26ac9de7814ee212d4","toggled":true},{"name":"main.go","path":"codegen/generate-securityhub/main.go","sha":"c7b20c0d8d573d140b14a9da9f002215641fc6ca"},{"name":"static","children":[{"name":"README.adoc","path":"codegen/generate-securityhub/static/README.adoc","sha":"7ab2155fa9a03eb4a8e6d0e0fcc8fefad3e4254f"},{"name":"core-concepts.md","path":"codegen/generate-securityhub/static/core-concepts.md","sha":"6307ca9d06fb54f2d0061a81290ffead6bf5e7fa"},{"name":"invite-external-accounts","children":[{"name":"build_scripts","children":[{"name":"build.sh","path":"codegen/generate-securityhub/static/invite-external-accounts/build_scripts/build.sh","sha":"d88b72cd2e82f5156a50a35fb8cfa238159c6f82"}]},{"name":"dev_requirements.txt","path":"codegen/generate-securityhub/static/invite-external-accounts/dev_requirements.txt","sha":"ff7dfc3a64633aa716313a6adc39a95412bb9da8"},{"name":"invite_external_accounts","children":[{"name":"__init__.py","path":"codegen/generate-securityhub/static/invite-external-accounts/invite_external_accounts/__init__.py","sha":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"},{"name":"errors.py","path":"codegen/generate-securityhub/static/invite-external-accounts/invite_external_accounts/errors.py","sha":"7dc0edfd882b693d431c6fc8c345bdc1be70e520"},{"name":"main.py","path":"codegen/generate-securityhub/static/invite-external-accounts/invite_external_accounts/main.py","sha":"3cbba395f54591fd4d13750a5c07fccc061236bb"},{"name":"project_logging.py","path":"codegen/generate-securityhub/static/invite-external-accounts/invite_external_accounts/project_logging.py","sha":"82c5fecd96fc2531417d0ac09f4adedd39fc169b"},{"name":"securityhub.py","path":"codegen/generate-securityhub/static/invite-external-accounts/invite_external_accounts/securityhub.py","sha":"d40b61026878f522afebc9172d1d4b8bba7074e2"}]},{"name":"invite_external_accounts_pex.tar","path":"codegen/generate-securityhub/static/invite-external-accounts/invite_external_accounts_pex.tar","sha":"35d9ea3ff4b964125095d80d49276b86ed38558c"},{"name":"requirements.txt","path":"codegen/generate-securityhub/static/invite-external-accounts/requirements.txt","sha":"a40be0ee80ae138ac17fe8e4015ecfc5115b29c0"}]},{"name":"variables.tf","path":"codegen/generate-securityhub/static/variables.tf","sha":"86d66fb4c2861dac9f088047f58ee7efb124543e"}]},{"name":"template_data.go","path":"codegen/generate-securityhub/template_data.go","sha":"fa040a005387677e1e17a6e7516f581e12d9f9e9"}],"toggled":true},{"name":"go.mod","path":"codegen/go.mod","sha":"c39f1f8474eedb9f179d2d4ba9bd39d6b191cb9b"},{"name":"go.sum","path":"codegen/go.sum","sha":"5baeca1e4232b2bfd89fe7c9fbb92425d572077b"}],"toggled":true},{"name":"examples","children":[{"name":"cloudtrail","children":[{"name":"terraform","children":[{"name":"README.md","path":"examples/cloudtrail/terraform/README.md","sha":"649683a26bf72c79ece3d337cd1054d940f24ded"},{"name":"main.tf","path":"examples/cloudtrail/terraform/main.tf","sha":"b4fbcdc0812484e50d6a5a85f7e0a01a5554f220"},{"name":"outputs.tf","path":"examples/cloudtrail/terraform/outputs.tf","sha":"d761e149fa2b1a22c74727b0f7ef1329f3063037"},{"name":"variables.tf","path":"examples/cloudtrail/terraform/variables.tf","sha":"81d4f4bb2ea1131763003f85de7b2e88f800f241"}]},{"name":"terragrunt","children":[{"name":"README.md","path":"examples/cloudtrail/terragrunt/README.md","sha":"cdc1635aef8a86985e80cc7bd8dc6c36137e9edf"},{"name":"terragrunt.hcl","path":"examples/cloudtrail/terragrunt/terragrunt.hcl","sha":"64a8047867d9b341b3d11ea07a492e8fcd4367cb"}]}]},{"name":"cloudwatch-logs-metric-filters","children":[{"name":"terraform","children":[{"name":"README.md","path":"examples/cloudwatch-logs-metric-filters/terraform/README.md","sha":"fe9e01f99c45176e0af002fbdf18269c30097714"},{"name":"main.tf","path":"examples/cloudwatch-logs-metric-filters/terraform/main.tf","sha":"8ccb2e619843d8af516755b85da00480717dddfb"},{"name":"outputs.tf","path":"examples/cloudwatch-logs-metric-filters/terraform/outputs.tf","sha":"074e6118f58a6fd89d339ee3561c241b5de3583e"},{"name":"variables.tf","path":"examples/cloudwatch-logs-metric-filters/terraform/variables.tf","sha":"8e9c4651d9a5d79026c591b18616600499b1bdd9"}]},{"name":"terragrunt","children":[{"name":"README.md","path":"examples/cloudwatch-logs-metric-filters/terragrunt/README.md","sha":"5428ae138344bcb31a29bf653de47adbacf65976"},{"name":"terragrunt.hcl","path":"examples/cloudwatch-logs-metric-filters/terragrunt/terragrunt.hcl","sha":"4782ce6b03c26c43f2d0849d1baa0298edc5e13b"}]}]},{"name":"cross-account-iam-roles","children":[{"name":"terraform","children":[{"name":"README.md","path":"examples/cross-account-iam-roles/terraform/README.md","sha":"1fe9486482282071f4f86113923832441f389fbf"},{"name":"main.tf","path":"examples/cross-account-iam-roles/terraform/main.tf","sha":"26aca4cd77367b7424078fd4cfe042ce6f37b447"},{"name":"outputs.tf","path":"examples/cross-account-iam-roles/terraform/outputs.tf","sha":"4635d74afd5ba0289decfaabe9e57266621866e2"},{"name":"variables.tf","path":"examples/cross-account-iam-roles/terraform/variables.tf","sha":"1c80da1943250d2c40180963c0a2f89fb2df9175"}]},{"name":"terragrunt","children":[{"name":"README.md","path":"examples/cross-account-iam-roles/terragrunt/README.md","sha":"bac0b37e9f2a156569390b4c3504ec4153462aa4"},{"name":"terragrunt.hcl","path":"examples/cross-account-iam-roles/terragrunt/terragrunt.hcl","sha":"eb5224cea7b8e53a085045e490a79005e7814cf4"}]}]},{"name":"custom-iam-entity","children":[{"name":"terraform","children":[{"name":"README.md","path":"examples/custom-iam-entity/terraform/README.md","sha":"3aab55b2e5ab522b79d028904ba9de832e9465e7"},{"name":"main.tf","path":"examples/custom-iam-entity/terraform/main.tf","sha":"33a2fc66826b737702aef28787ab83d9545b58c2"},{"name":"outputs.tf","path":"examples/custom-iam-entity/terraform/outputs.tf","sha":"835eb64f431386925438cb2f63e48e413faee90c"},{"name":"variables.tf","path":"examples/custom-iam-entity/terraform/variables.tf","sha":"7539c565d899f88078983f2232c550361a0ee502"}]},{"name":"terragrunt","children":[{"name":"README.md","path":"examples/custom-iam-entity/terragrunt/README.md","sha":"f29d07f8ffe7e2a8918e3e75ae9f2c1072f82a1c"},{"name":"terragrunt.hcl","path":"examples/custom-iam-entity/terragrunt/terragrunt.hcl","sha":"99bdccc50f04f2efb82ba424e86926066fddacff"}]}]},{"name":"iam-groups","children":[{"name":"terraform","children":[{"name":"README.md","path":"examples/iam-groups/terraform/README.md","sha":"bb42f2a822c2e6fd1f6c0b55e4eeef81066c06c0"},{"name":"main.tf","path":"examples/iam-groups/terraform/main.tf","sha":"852d3e363fa4aab098cfcb7b382f145a246f7e5e"},{"name":"outputs.tf","path":"examples/iam-groups/terraform/outputs.tf","sha":"f386fa2f8b93fddfc8a04cb067220e4297c03ada"},{"name":"variables.tf","path":"examples/iam-groups/terraform/variables.tf","sha":"154f5a51e416bec433824942c65199bc74f28321"}]},{"name":"terragrunt","children":[{"name":"README.md","path":"examples/iam-groups/terragrunt/README.md","sha":"693eb9b7a7bd820d40b016931a61989bff2c8be8"},{"name":"terragrunt.hcl","path":"examples/iam-groups/terragrunt/terragrunt.hcl","sha":"de01124a0a417059d5b62bf1cbb1352f4063ba24"}]}]},{"name":"iam-password-policy","children":[{"name":"terraform","children":[{"name":"README.md","path":"examples/iam-password-policy/terraform/README.md","sha":"26651683bdfbf526f289e779278e7861ee4fbc48"},{"name":"main.tf","path":"examples/iam-password-policy/terraform/main.tf","sha":"6cfd3decf581247ab410c1a6966b52c8d6f3d2da"},{"name":"variables.tf","path":"examples/iam-password-policy/terraform/variables.tf","sha":"ee9fe6604ee7b34c3a59b42cb9bcc503e5707abc"}]},{"name":"terragrunt","children":[{"name":"README.md","path":"examples/iam-password-policy/terragrunt/README.md","sha":"207bb1ad3e44c64e0e70c73de185e1f42b68756b"},{"name":"terragrunt.hcl","path":"examples/iam-password-policy/terragrunt/terragrunt.hcl","sha":"9a5abfb7982ee98aace97a1ea691a948aab5929e"}]}]},{"name":"saml-iam-roles","children":[{"name":"terraform","children":[{"name":"README.md","path":"examples/saml-iam-roles/terraform/README.md","sha":"a00fd7cc39b77395657aee02b5b50f25b60d97bb"},{"name":"main.tf","path":"examples/saml-iam-roles/terraform/main.tf","sha":"f669a1c4418c2249b5f850ac1614d64439db542b"},{"name":"outputs.tf","path":"examples/saml-iam-roles/terraform/outputs.tf","sha":"6e69339e781035cc29323a9dda927bea8a3d115b"},{"name":"saml-metadata.xml","path":"examples/saml-iam-roles/terraform/saml-metadata.xml","sha":"88596cfde52242a43559c79216a1c60b2ea12903"},{"name":"variables.tf","path":"examples/saml-iam-roles/terraform/variables.tf","sha":"7e552ab7a080ca8b9f4d0fd2b2058cda4b75c0c3"}]},{"name":"terragrunt","children":[{"name":"README.md","path":"examples/saml-iam-roles/terragrunt/README.md","sha":"00f9e3e903f4ebc4eeed20bff8f06546c546388d"},{"name":"terragrunt.hcl","path":"examples/saml-iam-roles/terragrunt/terragrunt.hcl","sha":"68c50d324603caa08181d1744b315c75e3697df8"}]}]},{"name":"securityhub","children":[{"name":"terragrunt","children":[{"name":"README.md","path":"examples/securityhub/terragrunt/README.md","sha":"e37eac4f45aab63a46d5b04d08ed53a6ac2471fe"},{"name":"master","children":[{"name":"terragrunt.hcl","path":"examples/securityhub/terragrunt/master/terragrunt.hcl","sha":"43f9e1834d0ccde7de6ebd01657078e73cba7574"}]},{"name":"member","children":[{"name":"terragrunt.hcl","path":"examples/securityhub/terragrunt/member/terragrunt.hcl","sha":"e27e078840046a1fff817ff84ba47a9a26c2fac9"}]}]}]}]},{"name":"modules","children":[{"name":"aws-securityhub","children":[{"name":"README.adoc","path":"modules/aws-securityhub/README.adoc","sha":"7ab2155fa9a03eb4a8e6d0e0fcc8fefad3e4254f"},{"name":"core-concepts.md","path":"modules/aws-securityhub/core-concepts.md","sha":"6307ca9d06fb54f2d0061a81290ffead6bf5e7fa"},{"name":"invite-external-accounts","children":[{"name":"bin","children":[{"name":"invite_external_accounts_py27_env.pex","path":"modules/aws-securityhub/invite-external-accounts/bin/invite_external_accounts_py27_env.pex","sha":"a61d838d1fd681fd56760c4ab3c9b8ef7750e051"},{"name":"invite_external_accounts_py3_env.pex","path":"modules/aws-securityhub/invite-external-accounts/bin/invite_external_accounts_py3_env.pex","sha":"d1afb0ae6efe358dd053458799367c0bb29e0614"}]},{"name":"invite_external_accounts","children":[{"name":"__init__.py","path":"modules/aws-securityhub/invite-external-accounts/invite_external_accounts/__init__.py","sha":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"},{"name":"errors.py","path":"modules/aws-securityhub/invite-external-accounts/invite_external_accounts/errors.py","sha":"7dc0edfd882b693d431c6fc8c345bdc1be70e520"},{"name":"main.py","path":"modules/aws-securityhub/invite-external-accounts/invite_external_accounts/main.py","sha":"3cbba395f54591fd4d13750a5c07fccc061236bb"},{"name":"project_logging.py","path":"modules/aws-securityhub/invite-external-accounts/invite_external_accounts/project_logging.py","sha":"82c5fecd96fc2531417d0ac09f4adedd39fc169b"},{"name":"securityhub.py","path":"modules/aws-securityhub/invite-external-accounts/invite_external_accounts/securityhub.py","sha":"d40b61026878f522afebc9172d1d4b8bba7074e2"}]}]},{"name":"main.tf","path":"modules/aws-securityhub/main.tf","sha":"2621f18cd060eeab76ff15c0ad50dc15a0e3f072"},{"name":"outputs.tf","path":"modules/aws-securityhub/outputs.tf","sha":"6ef6622d5e3b4575b7de0ede63272990d6d84c35"},{"name":"variables.tf","path":"modules/aws-securityhub/variables.tf","sha":"86d66fb4c2861dac9f088047f58ee7efb124543e"}]},{"name":"cloudtrail","children":[{"name":"README.adoc","path":"modules/cloudtrail/README.adoc","sha":"c8d0a4e5f5fe44fa5dc41bc74aa36fbc191b21d4"},{"name":"images","children":[{"name":"cloudtrail-cis-architecture.png","path":"modules/cloudtrail/images/cloudtrail-cis-architecture.png","sha":"70b296eb99f2c2da1bcc73fbb8d4528eb4743204"}]},{"name":"main.tf","path":"modules/cloudtrail/main.tf","sha":"68864581db72d48cb9c09a98ce7a765d09d5a72b"},{"name":"outputs.tf","path":"modules/cloudtrail/outputs.tf","sha":"33c67afdc73569394d1b43c182355156938d9b11"},{"name":"variables.tf","path":"modules/cloudtrail/variables.tf","sha":"8862afa2218c75cb0c2af079428bbd2358042b89"}]},{"name":"cloudwatch-logs-metric-filters","children":[{"name":"README.adoc","path":"modules/cloudwatch-logs-metric-filters/README.adoc","sha":"7f75dcb395f2cc6395950aefb5cf6849d3975e9f"},{"name":"core-concepts.md","path":"modules/cloudwatch-logs-metric-filters/core-concepts.md","sha":"75301bd203c74458fc05857510fdf89188ef3921"},{"name":"images","children":[{"name":"cloudwatch-alarm.png","path":"modules/cloudwatch-logs-metric-filters/images/cloudwatch-alarm.png","sha":"b9fa4a893e9a4c402f117d4fa3922b4e5fdc0b4f"},{"name":"cloudwatch-logs-architecture.png","path":"modules/cloudwatch-logs-metric-filters/images/cloudwatch-logs-architecture.png","sha":"65a8d960553521dbcb5d2342609b648fc1397f91"}]},{"name":"main.tf","path":"modules/cloudwatch-logs-metric-filters/main.tf","sha":"ed801c84926b89fe7753a6bf02e8bca0327a790e"},{"name":"outputs.tf","path":"modules/cloudwatch-logs-metric-filters/outputs.tf","sha":"1d0237d1e1bf5ba6d9e2136ecf1f2bf047ec7063"},{"name":"variables.tf","path":"modules/cloudwatch-logs-metric-filters/variables.tf","sha":"09c5655a6cd58fab958bea3afe91cc2287bfc248"}]},{"name":"cross-account-iam-roles","children":[{"name":"README.adoc","path":"modules/cross-account-iam-roles/README.adoc","sha":"081ea89c0912444bc7e9e0058910092884fa9cb3"},{"name":"images","children":[{"name":"iam-roles-architecture.png","path":"modules/cross-account-iam-roles/images/iam-roles-architecture.png","sha":"5b7c1e935fac59214299e224eb8425c8c9b246b8"}]},{"name":"main.tf","path":"modules/cross-account-iam-roles/main.tf","sha":"ced23a20d145023b87a22a9cf90ce9841500b757"},{"name":"outputs.tf","path":"modules/cross-account-iam-roles/outputs.tf","sha":"4635d74afd5ba0289decfaabe9e57266621866e2"},{"name":"variables.tf","path":"modules/cross-account-iam-roles/variables.tf","sha":"d7835df3cc93a9a0d858ac824f213144e419168b"}]},{"name":"custom-iam-entity","children":[{"name":"README.adoc","path":"modules/custom-iam-entity/README.adoc","sha":"b30df86a761f4640c90e3a8fbf376e9d3a24888d"},{"name":"main.tf","path":"modules/custom-iam-entity/main.tf","sha":"4b0a1e7443048694d727d5a64015e12dce4026e3"},{"name":"outputs.tf","path":"modules/custom-iam-entity/outputs.tf","sha":"157e624e8e8610fbeaf54f603dce2516806c332f"},{"name":"variables.tf","path":"modules/custom-iam-entity/variables.tf","sha":"9a4e12646a30d1bfee9ce18b28e134dad19983da"}]},{"name":"iam-groups","children":[{"name":"README.adoc","path":"modules/iam-groups/README.adoc","sha":"bd8a0a3a77ac0d40385c804635b108a14d2750db"},{"name":"core-concepts.md","path":"modules/iam-groups/core-concepts.md","sha":"02dc8472d42c7ae6497417b378f31e8bd9882bd9"},{"name":"images","children":[{"name":"iam-groups-architecture.png","path":"modules/iam-groups/images/iam-groups-architecture.png","sha":"c95384f4ee5e543cda1b39bbfe6239f9581609f0"}]},{"name":"main.tf","path":"modules/iam-groups/main.tf","sha":"0540e498e623a11d60316cfbc6949b3767f65ba3"},{"name":"outputs.tf","path":"modules/iam-groups/outputs.tf","sha":"0919bcae3e51cadad70355a2c52fd15b45434287"},{"name":"variables.tf","path":"modules/iam-groups/variables.tf","sha":"a24e2fb4548de52da24e1c7eb8b3a2078b44c552"}]},{"name":"iam-password-policy","children":[{"name":"README.adoc","path":"modules/iam-password-policy/README.adoc","sha":"55fd68765af71303c4d1db6d249a245cf37a7540"},{"name":"main.tf","path":"modules/iam-password-policy/main.tf","sha":"7438c6148e697e1ec28537b86f1e3f4a3111393d"},{"name":"variables.tf","path":"modules/iam-password-policy/variables.tf","sha":"e8c3867f0ef9eb1a1d253ef6d5dffe6c902a4221"}]},{"name":"saml-iam-roles","children":[{"name":"README.adoc","path":"modules/saml-iam-roles/README.adoc","sha":"26de3c0843d0ea4436fdf19dd60cb569a2be3402"},{"name":"images","children":[{"name":"saml-iam-roles.png","path":"modules/saml-iam-roles/images/saml-iam-roles.png","sha":"d8bb2b15ad1fbcb4cb0f823663735edc469d0c14"}]},{"name":"main.tf","path":"modules/saml-iam-roles/main.tf","sha":"1bcacf255b990ba9ea71d8a90cf363af7cac4020"},{"name":"outputs.tf","path":"modules/saml-iam-roles/outputs.tf","sha":"6e69339e781035cc29323a9dda927bea8a3d115b"},{"name":"variables.tf","path":"modules/saml-iam-roles/variables.tf","sha":"4319d117656b5a6945009dd15d62083af779852e"}]}]},{"name":"rfcs","children":[{"name":"flexible-backends.md","path":"rfcs/flexible-backends.md","sha":"8c308f20484932b9773c07f127d498de14c76bae"}]},{"name":"setup.cfg","path":"setup.cfg","sha":"981bc2bfd0b35029438d56c6d862a7f1519b8fe6"},{"name":"test","children":[{"name":"cloudtrail_test.go","path":"test/cloudtrail_test.go","sha":"46669ddd1b32aeb3f959a8dac9000d599bcbb03a"},{"name":"cloudwatch_logs_metric_filters_test.go","path":"test/cloudwatch_logs_metric_filters_test.go","sha":"1110d7f0ddeeda36fff67ffaf49fd326a71dc83c"},{"name":"cross_account_iam_roles_test.go","path":"test/cross_account_iam_roles_test.go","sha":"aa6d75cf953722a65edd0f623fe76a142c9aa02a"},{"name":"custom_iam_entity_test.go","path":"test/custom_iam_entity_test.go","sha":"4c95a46959349aeba26e80131a35af96ab16955a"},{"name":"generate_securityhub_test.go","path":"test/generate_securityhub_test.go","sha":"492a4a86011210beb598ad1fdeb73736fec1a27e"},{"name":"go.mod","path":"test/go.mod","sha":"ae654fc7163a2df0241010e098b6456fe1dc965e"},{"name":"go.sum","path":"test/go.sum","sha":"3e43d17a39b86941caf74aa75e470cb35ced4ddd"},{"name":"iam_groups_test.go","path":"test/iam_groups_test.go","sha":"a361792deea45a980ed7ceae6f7a759c20c5ae3a"},{"name":"iam_password_policy_test.go","path":"test/iam_password_policy_test.go","sha":"0402874302c76da6e7fdf035a6b688e39ef33d8c"},{"name":"saml_iam_roles_test.go","path":"test/saml_iam_roles_test.go","sha":"7fc7ae5a4a268b6b78e90830ac150a98c92bfd82"},{"name":"test_helpers.go","path":"test/test_helpers.go","sha":"f0614e492133b9e9b9bbaec4b34251493d31f4cd"}]}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"aws-security-hub-module-generator\">AWS Security Hub Module Generator</h1><div class=\"preview__body--border\"></div><p>This folder contains a program called <code>generate-securityhub</code> which is used to manage the <a href=\"/repos/v0.5.1/cis-compliance-aws/modules/aws-securityhub\" class=\"preview__body--description--blue\">aws-securityhub\nmodule</a> in this repo. The code generator is used to make it easier to manage terraform blocks\nthat need to apply to more than one region.</p>\n<h2 class=\"preview__body--subtitle\" id=\"installation\">Installation</h2>\n<p><code>generate-securityhub</code> is a single, self-contained, statically compiled binary written in Go. The easiest way to get it onto your servers is to use the <a href=\"/repos/gruntwork-installer\" class=\"preview__body--description--blue\">Gruntwork\nInstaller</a> (make sure to replace <code><VERSION></code> below with the latest\nversion from the <a href=\"#open_modal\" class=\"preview__body--description--blue\">releases page</a>):</p>\n<pre>gruntwork-install --binary-name <span class=\"hljs-keyword\">generate</span>-securityhub --repo https:<span class=\"hljs-comment\">//github.com/gruntwork-io/cis-compliance-aws --tag <VERSION></span>\n</pre>\n<p>Alternatively, you can download the binary from the <a href=\"#open_modal\" class=\"preview__body--description--blue\">Releases\nPage</a>.</p>\n<h2 class=\"preview__body--subtitle\" id=\"usage\">Usage</h2>\n<p>This command should be run in the <code>modules</code> folder of this repo. This command will output the autogenerated contents of\nthe <code>aws-securityhub</code> module that can be used to enable AWS Security Hub on all enabled regions of an account.</p>\n<p>Note that you can also use this command to generate the module in a different folder, such as your own\n<code>infrastructure-modules</code> repo.</p>\n<p>For example, suppose you had an <code>infrastructure-modules</code> repository that mimics the Gruntwork Reference Architecture,\nand has the following structure:</p>\n<pre><span class=\"hljs-selector-tag\">infrastructure-modules</span>\n├── <span class=\"hljs-selector-tag\">README</span><span class=\"hljs-selector-class\">.md</span>\n├── <span class=\"hljs-selector-tag\">data-stores</span>\n│ └── <span class=\"hljs-selector-tag\">rds</span>\n│ ├── <span class=\"hljs-selector-tag\">README</span><span class=\"hljs-selector-class\">.md</span>\n│ ├── <span class=\"hljs-selector-tag\">main</span><span class=\"hljs-selector-class\">.tf</span>\n│ ├── <span class=\"hljs-selector-tag\">outputs</span><span class=\"hljs-selector-class\">.tf</span>\n│ └── <span class=\"hljs-selector-tag\">variables</span><span class=\"hljs-selector-class\">.tf</span>\n└── <span class=\"hljs-selector-tag\">security</span>\n ├── <span class=\"hljs-selector-tag\">iam-groups</span>\n │ ├── <span class=\"hljs-selector-tag\">README</span><span class=\"hljs-selector-class\">.md</span>\n │ ├── <span class=\"hljs-selector-tag\">main</span><span class=\"hljs-selector-class\">.tf</span>\n │ ├── <span class=\"hljs-selector-tag\">outputs</span><span class=\"hljs-selector-class\">.tf</span>\n │ └── <span class=\"hljs-selector-tag\">variables</span><span class=\"hljs-selector-class\">.tf</span>\n └── <span class=\"hljs-selector-tag\">cloudtrail</span>\n ├── <span class=\"hljs-selector-tag\">README</span><span class=\"hljs-selector-class\">.md</span>\n ├── <span class=\"hljs-selector-tag\">main</span><span class=\"hljs-selector-class\">.tf</span>\n ├── <span class=\"hljs-selector-tag\">outputs</span><span class=\"hljs-selector-class\">.tf</span>\n └── <span class=\"hljs-selector-tag\">variables</span><span class=\"hljs-selector-class\">.tf</span>\n</pre>\n<p>Suppose that you now want to add a module <code>aws-securityhub</code> as generated by this script in the <code>security</code> folder. To do\nso, first install the binary so that it is available in your <code>PATH</code> as described in the <a href=\"#installation\" class=\"preview__body--description--blue\">Installation section of this\ndocs</a>.</p>\n<p>Next, run the generator in the <code>infrastructure-modules</code> directory, passing in the target directory and main region. Note\nthat you will need to be authenticated to your AWS account. Refer to the <a href=\"https://blog.gruntwork.io/a-comprehensive-guide-to-authenticating-to-aws-on-the-command-line-63656a686799\" class=\"preview__body--description--blue\" target=\"_blank\">Comprehensive Guide to Authenticating to AWS\non the Command\nLine</a> for\nrecommended ways to authenticate on the command line.</p>\n<pre><span class=\"hljs-keyword\">generate</span>-securityhub --target-directory ./security/aws-securityhub\n</pre>\n<p>At the end of this command, you should see the <code>aws-securityhub</code> module generated in your <code>infrastructure-modules</code>\nrepository:</p>\n<pre><span class=\"hljs-selector-tag\">infrastructure-modules</span>\n├── <span class=\"hljs-selector-tag\">README</span><span class=\"hljs-selector-class\">.md</span>\n├── <span class=\"hljs-selector-tag\">data-stores</span>\n│ └── <span class=\"hljs-selector-tag\">rds</span>\n│ ├── <span class=\"hljs-selector-tag\">README</span><span class=\"hljs-selector-class\">.md</span>\n│ ├── <span class=\"hljs-selector-tag\">main</span><span class=\"hljs-selector-class\">.tf</span>\n│ ├── <span class=\"hljs-selector-tag\">outputs</span><span class=\"hljs-selector-class\">.tf</span>\n│ └── <span class=\"hljs-selector-tag\">variables</span><span class=\"hljs-selector-class\">.tf</span>\n└── <span class=\"hljs-selector-tag\">security</span>\n ├── <span class=\"hljs-selector-tag\">aws-securityhub</span>\n │ ├── <span class=\"hljs-selector-tag\">invite-external-accounts</span>\n │ ├── <span class=\"hljs-selector-tag\">README</span><span class=\"hljs-selector-class\">.adoc</span>\n │ ├── <span class=\"hljs-selector-tag\">main</span><span class=\"hljs-selector-class\">.tf</span>\n │ ├── <span class=\"hljs-selector-tag\">outputs</span><span class=\"hljs-selector-class\">.tf</span>\n │ └── <span class=\"hljs-selector-tag\">variables</span><span class=\"hljs-selector-class\">.tf</span>\n ├── <span class=\"hljs-selector-tag\">iam-groups</span>\n │ ├── <span class=\"hljs-selector-tag\">README</span><span class=\"hljs-selector-class\">.md</span>\n │ ├── <span class=\"hljs-selector-tag\">main</span><span class=\"hljs-selector-class\">.tf</span>\n │ ├── <span class=\"hljs-selector-tag\">outputs</span><span class=\"hljs-selector-class\">.tf</span>\n │ └── <span class=\"hljs-selector-tag\">variables</span><span class=\"hljs-selector-class\">.tf</span>\n └── <span class=\"hljs-selector-tag\">cloudtrail</span>\n ├── <span class=\"hljs-selector-tag\">README</span><span class=\"hljs-selector-class\">.md</span>\n ├── <span class=\"hljs-selector-tag\">main</span><span class=\"hljs-selector-class\">.tf</span>\n ├── <span class=\"hljs-selector-tag\">outputs</span><span class=\"hljs-selector-class\">.tf</span>\n └── <span class=\"hljs-selector-tag\">variables</span><span class=\"hljs-selector-class\">.tf</span>\n\n</pre>\n<p>You can now invoke the module using Terragrunt, or any other production Terraform frontend that you are currently using.</p>\n<h2 class=\"preview__body--subtitle\" id=\"building-the-binary\">Building the Binary</h2>\n<p>We use <a href=\"https://github.com/gobuffalo/packr\" class=\"preview__body--description--blue\" target=\"_blank\">packr</a> to compile the templates into the binary so that it is portable. To\ndo so, we need to run <code>packr2</code> prior to building the binaries.</p>\n<p>Here are the steps for compiling from source:</p>\n<ul>\n<li>Install the <code>packr2</code> binary: <code>go get -u github.com/gobuffalo/packr/v2/packr2</code></li>\n<li>Run <code>$GOPATH/bin/packr2</code>. This will convert the template files into go files so that they are available in the go\nbinary.</li>\n<li>Mark gruntwork-io as private repos so that they are fetched with ssh: <code>go env -w GOPRIVATE=github.com/gruntwork-io</code></li>\n<li>Build the <code>generate-securityhub</code> binary: <code>go build -o $BIN_PATH .</code></li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"working-with-the-invite-external-accounts-python-script\">Working with the invite-external-accounts Python Script</h2>\n<p>Since terraform currently does not support managing Security Hub multi account memberships, we use python with the\n<code>boto3</code> library to workaround it. The script to handle the logic for managing multi account memberships is shipped with\nthe generated <code>aws-securityhub</code> module. The source code for the script lives in <code>data/static/invite-external-accounts</code>.</p>\n<p>To support portability of the python libraries, we package all the dependencies of the scripts into a\n<a href=\"https://pex.readthedocs.io/en/stable/whatispex.html\" class=\"preview__body--description--blue\" target=\"_blank\">pex file</a>. This pex file must be distributed with the module in\norder to be correctly called by <code>terraform</code> without the user having to install extra python dependencies into their\nsystem.</p>\n<p>As such, the operator machine consuming the module must have a valid python interpreter available in the <code>PATH</code> under\nthe name <code>python</code>. The pex binary supports python versions 2.7, 3.5, 3.6, and 3.7, on Mac OSX or Linux.</p>\n<h3 class=\"preview__body--subtitle\" id=\"building-the-binary\">Building the binary</h3>\n<p>The pex binary is a python executable that includes the necessary third party requirements. This special version of python\nembeds cross platform versions of the requirements that are unpacked at runtime into a\n<a href=\"https://virtualenv.pypa.io/en/stable/\" class=\"preview__body--description--blue\" target=\"_blank\">virtualenv</a>. This executable is then used to call out to the entrypoint script,\nwhich will import the library function.</p>\n<p>As such, the binary only needs to be built when the requirements change. You do not need to rebuild the binary for any\nchanges to the source files in the <code>invite_external_accounts</code> library.</p>\n<p>This approach is taken so that consumers of the module do not need to install additional third party libraries on top of\npython to utilize the script. To make this work, the <code>pex</code> binaries need to be checked into the repository so that they\nare distributed with the module.</p>\n<p>The binary is generated using the <a href=\"https://pex.readthedocs.io/en/stable/whatispex.html\" class=\"preview__body--description--blue\" target=\"_blank\"><code>pex</code></a> utility. Pex will package\nthe python script with all its requirements into a single binary, that can be made to be compatible with multiple\nversions of python and multiple OS platforms.</p>\n<p>To build the binary, you will need the following:</p>\n<ul>\n<li>A working python environment with <strong>all compatible versions of python</strong> setup (so that you can build binaries for all\nversions)</li>\n<li>pex installed (use <code>pip install -r dev_requirements.txt</code>)</li>\n</ul>\n<p>You can then build the binary using the helper script <code>build_scripts/build.sh</code> which will build the binary and create a\ntarball containing the binaries. This tarball should be checked in so that the <code>generate-securityhub</code> utility can\ndistribute it with the generated Terraform module.</p>\n<p>It is recommended to use <a href=\"https://github.com/pyenv/pyenv\" class=\"preview__body--description--blue\" target=\"_blank\"><code>pyenv</code></a> to help setup an environment with multiple python\ninterpreters. The latest binaries are built with the following python environment:</p>\n<pre>pyenv shell <span class=\"hljs-number\">2.7</span><span class=\"hljs-number\">.15</span> <span class=\"hljs-number\">3.5</span><span class=\"hljs-number\">.2</span> <span class=\"hljs-number\">3.6</span><span class=\"hljs-number\">.6</span> <span class=\"hljs-number\">3.7</span><span class=\"hljs-number\">.0</span>\n</pre>\n","repoName":"cis-compliance-aws","repoRef":"v0.4.1","serviceDescriptor":{"serviceName":"CIS Foundations Benchmark","serviceRepoName":"cis-compliance-aws","serviceRepoOrg":"gruntwork-io","cloudProviders":["aws"],"description":"Modules and utilities certified by Gruntwork and CIS to comply with the CIS AWS Foundations Benchmark","imageUrl":"cis-logo.png","licenseType":"subscriber","technologies":["Terraform","Go","Python"],"compliance":["CIS"],"tags":[""]},"serviceCategoryName":"Compliance","fileName":"README.md","filePath":"/codegen/generate-securityhub","title":"Repo Browser: CIS Foundations Benchmark","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}