You can use AWS CloudTrail to get a history of AWS API calls and related events for your account. This includes calls
made by using the AWS Management Console, AWS SDKs, command line tools, and higher-level AWS services.
Why use CloudTrail?
An important element of cloud security is auditing all AWS API calls. This can give you key insight into when a new port
was opened, when a new IAM User account was created, and other security-significant events. While it's trivially easy to
turn on CloudTrail, thinking through where to store CloudTrail logs, how to guarantee CloudTrails logs aren't tampered
with, and getting alerts when certain API events occur is non-trivial.
Note that any interaction with AWS ultimately results in an API call. This includes using the AWS Web Console, awscli,
and any of the various AWS SDKs.
What is a CloudTrail Trail?
To setup CloudTrail, you enable an individual "Trail" which has certain configuration options. For example, a Trail could
be configured to collect logs from just a single AWS Region or all AWS Regions, it could optionally log to CloudWatch Logs,
optionally use a KMS Key, etc.
In practice, most teams will use a single CloudTrail Trail.
What's the difference between CloudTrail and AWS Config?
CloudTrail records every API call event in log files and provides convenient ways of viewing those logs. It treats the
API Call as a first-class entity.
AWS Config tracks changes to individual AWS resources and can alert you when a change is made that violates a defined
policy. It treats the AWS Resource as a first-class entity.
Naturally, an API Call typically operates on a particular AWS Resource, so the AWS Web Console includes links to the
corresponding AWS Resource in AWS Config (and vice versa).
CloudTrail Threat Model
The following are the various parts of the cloudtrail module threat model:
Deleting the S3 Bucket that stores CloudTrail events. An IAM User who has permissions to delete the S3 Bucket that
contains all CloudTrail events can delete all historical log data by deleting the S3 Bucket. Interestingly, CloudTrail
will still show the last 7 days of create, modify, and delete API calls in the AWS Web Console, even after the S3
Bucket is deleted.
One way to protect against this is to set an alert if the S3 Bucket is deleted. In addition, an attacker could
delete the alert (!) so we also need an alert if any alerts are themselves deleted.
To assist with access auditing, you can also enable S3 Access Logs so that any access or modification of the CloudTrail S3
bucket will be logged to the separate S3 bucket. Of course, you'll need to ensure that the same user does not have access
to the access logs bucket.
Another option is to enable S3 Cross-Region Replication in
a cross-account scenario. That is, all S3 data is asynchronously replicated to another S3 Bucket in another AWS Account
which you limit access to a very small number of trusted parties.
Yet another option is to enable CloudWatch Logs integration so that CloudTrail events are published to a CloudWatch Logs
group. The same deletion risk exists for an IAM user who has access to CloudWatch Logs. This is one reason among many
why it is recommended to limit IAM access and prevent full administrator rights to any IAM user.
Resources Created
This module creates the following AWS resources:
aws_s3_bucket: An S3 Bucket where all CloudTrail data is stored. You can configure for how long CloudTrail data
is stored.
aws_kms_key: A KMS Customer Master Key (CMK) that encrypts all CloudTrail data. In order to view any read API log
entries, or any API log entries older than 7 days, a user must have "decrypt" rights on this Key.
aws_cloudtrail: We create a CloudTrail "Trail" that records log data from all AWS Regions and also writes a hash
of all log entries to S3 to allow for log file validation.
aws_cloudwatch_log_group: (optional) A CloudWatch Logs group where CloudTrail can publish events.
aws_iam_role: (optional) An IAM role for CloudTrail to use for publishing events to CloudWatch Logs.
Operations
Where are CloudTrail logs stored?
All CloudTrail log data is stored as discrete files in S3. This module configures those files to be encrypted with a KMS
Customer Master Key (CMK) used exclusively for CloudTrail.
What kind of data do CloudTrail log entries contain?
As you can see, pretty much all relevant information is included in the call, including the identity of the requester,
the user agent, and the service being called.
What's the best way to view CloudTrail Log Data?
One way to view CloudTrail log data is just to download files directly from S3. That's how I obtained the example above.
The other way to view log data is directly in the AWS Web Console, which provides a convenient interface for viewing and
filtering all API activity for create, modify, and delete API calls for the last 7 days only.
To view read API calls, or any data older than 7 days, you must access it directly in S3.
Another approach is to view the logs in CloudWatch Logs. If the trail is configured to publish to a CloudWatch Logs group, each
event as described above is visible as a separate entry in the log group.
Tip: IAM Users with IAM-granted access to CloudTrail can still view some data. See the Gotchas for details.
Can you get alerted when certain API events occur?
Yes. It's possible to configure CloudTrail to also log events in CloudWatch Logs.
You can then configure CloudWatch Logs to emit a custom CloudWatch metric for certain events, and then create a CloudWatch
alarm that notifies an SNS Topic when those events occur.
This module does not currently support those features, but if you'd like us to add them please email info@gruntwork.io.
Gotchas
Even if an IAM User doesn't have access to the KMS Key used to encrypt all CloudTrail log data, if they have the
appropriate IAM Policy, they can still view a subset of CloudTrail events in the AWS Web Console! Specifically, the
AWS Web Console shows most API activity for create, modify, and delete API calls for the last 7 days only. Note that some activity is not visible, such as SSM calls. Viewing
any other CloudTrail data does require access to the KMS Key.
CloudTrail logs are not delivered instantly to the S3 Bucket. There's typically a delay of a few minutes. While AWS
documentation states that it takes 15 minutes, in practice we've found it to be around 5 minutes in most cases.
CloudTrail records not only API calls made by human IAM Users, but also API calls made by IAM Roles, and even API calls
made on behalf of an IAM User by internal AWS Services. You can identify this last type of API call by looking for an
invokedBy property in the CloudTrail event. For example:
"invokedBy":"signin.amazonaws.com"
If you provide an existing S3 bucket rather than allow this module to create one, you'll need to apply the recommended
S3 Bucket Policy.
Furthermore, if you provide an existing S3 bucket, the module will not enable access logging even if you use
enable_s3_server_access_logging=true. The access logging bucket will be created, but you'll need to manually enable logging
in the bucket properties of the existing bucket.
Known Issues
Terraform has a bug where you will see a diff on the S3 lifecycle rules on every terraform apply or terraform plan. See
#9119 to track progress on this issue.
If you attempt to enable or disable archiving of log files, Terraform will attempt to delete and re-create your existing S3
Bucket. This will fail because your Bucket won't be empty, but more importantly, the goal here is just to change some S3
Lifecycle Rules, so a destroy/re-create is unnecessary.
Here's what the terraform plan output looks like if you attempt to disable archiving:
Fortunately, there's a 1-line workaround using Terraform's built-in state management features:
If you are ENABLING archiving:terraform state mv module.cloudtrail.aws_s3_bucket.cloudtrail_with_logs_archived module.cloudtrail.aws_s3_bucket.cloudtrail_with_logs_not_archived
If you are DISABLING archiving:terraform state mv module.cloudtrail.aws_s3_bucket.cloudtrail_with_logs_not_archived module.cloudtrail.aws_s3_bucket.cloudtrail_with_logs_archived
These commands tell Terraform to update the state file, and treat the bucket that Terraform wanted to create as already
existing. Now you'll get a yellow "modify" output when running terraform plan and no destroy/re-create will be needed.
TODO
Document CLI-based validation
of a CloudTrail log file to ensure it hasn't been tampered with.
Consider enabling MFA Delete on the S3 Bucket
that stores the CloudTrail events.
Implement support for CloudWatch Logs and declaring specific alerts on individual API events.
Examples:
Alert if CloudTrail Logging is paused.
Alert if CloudTrail S3 Bucket is deleted.
Alert if any IAM Policy, IAM User, or IAM Role is changed (or would this be too noisy?)
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":"96a51a30c7d0925c67a1e10b2d363348fa293da4"}]},{"name":".editorconfig","path":".editorconfig","sha":"a5eec1063e66c4cb953cba222dd50b4d314ef3e2"},{"name":".gitignore","path":".gitignore","sha":"db9544649ac09686ab10d48c26aa1d65fbd25fb7"},{"name":".pre-commit-config.yaml","path":".pre-commit-config.yaml","sha":"8d98e6d06e9c4d3f9b680dc9ab6d5ccc7f9d96d3"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"90f69ca352e026ce99027459bb83ea303410fcfd"},{"name":"LICENSE.txt","path":"LICENSE.txt","sha":"f4e3d9bd4717a044ed31ad847a300eee74371a78"},{"name":"README.adoc","path":"README.adoc","sha":"2fa6943dc66863a9f854a55374ed6b89f1dab998"},{"name":"_ci","children":[{"name":"output-debug-values.sh","path":"_ci/output-debug-values.sh","sha":"39d6d5f080a53f932e3b5ec970b5f268fd00e50a"}]},{"name":"_docs","children":[{"name":"auto-update.png","path":"_docs/auto-update.png","sha":"77bfd1c65de0245ac8b3c67d5b0b64fc440824bf"},{"name":"aws-cloudtrail-architecture.png","path":"_docs/aws-cloudtrail-architecture.png","sha":"a2dd9a08b8ed77744fd5febab3be7bdf633dee79"},{"name":"aws-cloudtrail.png","path":"_docs/aws-cloudtrail.png","sha":"acc7dcaf4b46ce3cef1bcc20be0329e12c320e7f"},{"name":"aws-config-architecture.png","path":"_docs/aws-config-architecture.png","sha":"721458048d5e539468c438498863a91fa96e0a85"},{"name":"aws-config-rules-architecture.png","path":"_docs/aws-config-rules-architecture.png","sha":"29fe3f20358b176e385d1bcdc0357bff2c1d5b4a"},{"name":"aws-config-rules.png","path":"_docs/aws-config-rules.png","sha":"ac3f7b35bcac949887e62aee260d9cb70edd3ae8"},{"name":"aws-config.png","path":"_docs/aws-config.png","sha":"02f4b326aef57372def4f3fafa4f0e4cec07e395"},{"name":"aws-guardduty.png","path":"_docs/aws-guardduty.png","sha":"053b92412fb8e3fb5740acc404b493fe1dd7229b"},{"name":"aws-organizations-architecture.png","path":"_docs/aws-organizations-architecture.png","sha":"bd57412fe85d3fe8d5e358db5e3b7bfef3e786a9"},{"name":"aws-organizations-icon.png","path":"_docs/aws-organizations-icon.png","sha":"b2b3fa04f51a23e5bae1b3389ffedf5e17b3cef2"},{"name":"kms-icon.png","path":"_docs/kms-icon.png","sha":"cd4f350a9a3fda41089928a7e396ee8924b7a901"},{"name":"multiaccount_guardduty.png","path":"_docs/multiaccount_guardduty.png","sha":"c56b50bbb4c2a041366b430cada27b88aa02524b"},{"name":"ssh-grunt-architecture.png","path":"_docs/ssh-grunt-architecture.png","sha":"9ced8c68bcc7957e50aa016cad6c5b043a05b470"},{"name":"terminal-icon.png","path":"_docs/terminal-icon.png","sha":"df09d52d5b1176d7e231bab6c7712c3728e45c1b"}]},{"name":"codegen","children":[{"name":"README.adoc","path":"codegen/README.adoc","sha":"985e83db4ee84bc073af9580c251646f08137ffc"},{"name":"core-concepts.md","path":"codegen/core-concepts.md","sha":"e207ee1fc37f7d0d768a667127ff30befa9598a7"},{"name":"generate-aws-config","children":[{"name":".gitignore","path":"codegen/generate-aws-config/.gitignore","sha":"b488f31b176e8da6501add7ce148074af2337d91"},{"name":"main.go","path":"codegen/generate-aws-config/main.go","sha":"716dbc819f484efd2bd671e98bbc59b597a5e3f0"},{"name":"static","children":[{"name":"README.adoc","path":"codegen/generate-aws-config/static/README.adoc","sha":"8f95c4e964a5a0f913139f1a8d3f3d31345e9c06"},{"name":"images","children":[{"name":"aws-config-architecture.png","path":"codegen/generate-aws-config/static/images/aws-config-architecture.png","sha":"721458048d5e539468c438498863a91fa96e0a85"}]},{"name":"variables.tf","path":"codegen/generate-aws-config/static/variables.tf","sha":"9fe96d49af6b90e85301b9ffcd7278bf863e1580"}]},{"name":"template_data.go","path":"codegen/generate-aws-config/template_data.go","sha":"37df10e1b8c9c7d058c2e2a799cb0578af9fa3fc"}]},{"name":"generate-aws-guardduty","children":[{"name":".gitignore","path":"codegen/generate-aws-guardduty/.gitignore","sha":"b488f31b176e8da6501add7ce148074af2337d91"},{"name":"main.go","path":"codegen/generate-aws-guardduty/main.go","sha":"65a8af5a54afd75c1123cf9905cac3a770ca210d"},{"name":"static","children":[{"name":"README.adoc","path":"codegen/generate-aws-guardduty/static/README.adoc","sha":"0c0833b9655d1d292f086b8f27c594ef1b968d68"},{"name":"variables.tf","path":"codegen/generate-aws-guardduty/static/variables.tf","sha":"992199e9e968a3006918b286c7f3e69eb2fbbd74"}]},{"name":"template_data.go","path":"codegen/generate-aws-guardduty/template_data.go","sha":"99aa2d3dd6e70fa736e6101e0ede935a59cec955"}]},{"name":"generate-multiregion-kms","children":[{"name":".gitignore","path":"codegen/generate-multiregion-kms/.gitignore","sha":"dd60654458233c0bdb18892c5989f1828889d55b"},{"name":"main.go","path":"codegen/generate-multiregion-kms/main.go","sha":"a4c0e0fefe40a90d724a054ceef68745871eb6e6"},{"name":"static","children":[{"name":"README.adoc","path":"codegen/generate-multiregion-kms/static/README.adoc","sha":"0e7764d5d98f2cc2f5decd6429ca3de22d4bed87"},{"name":"variables.tf","path":"codegen/generate-multiregion-kms/static/variables.tf","sha":"275c4784a01a704089fe9f7268161ad167082a4d"}]},{"name":"template_data.go","path":"codegen/generate-multiregion-kms/template_data.go","sha":"7ec2a39c066905afa345fd07881681f199ad700f"}]},{"name":"generator","children":[{"name":"aws.go","path":"codegen/generator/aws.go","sha":"5c4712b16f00ebfe3d9ab85e5ef7ec4e7376bd7e"},{"name":"cli.go","path":"codegen/generator/cli.go","sha":"6e92f692f11d26c182c9e987fd566b0b8cb10901"},{"name":"errors.go","path":"codegen/generator/errors.go","sha":"21fd1f6d4bef60ea9cb39939783696526ddd02e7"},{"name":"generator.go","path":"codegen/generator/generator.go","sha":"512cd371bdf1342885f4313f4bb607137f8e51f8"},{"name":"main.tf.tpl.go","path":"codegen/generator/main.tf.tpl.go","sha":"4c7fa4d24105f73af5edd4b7b28780c2ef1e3360"},{"name":"outputs.tf.tpl.go","path":"codegen/generator/outputs.tf.tpl.go","sha":"d5f5236e76f98825f082c5d2d125b5f4f0376f09"}]},{"name":"go.mod","path":"codegen/go.mod","sha":"10fc12445001ccc8061886f383e9a37ef704121f"},{"name":"go.sum","path":"codegen/go.sum","sha":"264a7a2d25f07c58b4fcc30125fc569b23f191dd"},{"name":"logging","children":[{"name":"logging.go","path":"codegen/logging/logging.go","sha":"d4fb9da710acb21567b4e0581cb7bd7692baca04"}]}]},{"name":"examples","children":[{"name":"account-baseline-app","children":[{"name":"README.md","path":"examples/account-baseline-app/README.md","sha":"f83d3b47c34e643ab41794a112b6d0a3439c929f"},{"name":"main.tf","path":"examples/account-baseline-app/main.tf","sha":"a82bc7d2e69c015ee708f1b92bd0bda754cfac26"},{"name":"outputs.tf","path":"examples/account-baseline-app/outputs.tf","sha":"e665d258e992d13639dee123987a8fe2751f29f6"},{"name":"variables.tf","path":"examples/account-baseline-app/variables.tf","sha":"3602f6653ee3de28b58b8be4cbe8f751d2dce9e9"}]},{"name":"account-baseline-root","children":[{"name":"README.md","path":"examples/account-baseline-root/README.md","sha":"3a03c317430f56d218acea7b819df2ad1ab75169"},{"name":"main.tf","path":"examples/account-baseline-root/main.tf","sha":"f33a9a5ce0f59e2b0e6a5d64159ec8f7d2eca4d7"},{"name":"outputs.tf","path":"examples/account-baseline-root/outputs.tf","sha":"4652997642ea8690f6adfea4af3f238fdff71500"},{"name":"variables.tf","path":"examples/account-baseline-root/variables.tf","sha":"4b60fdbd5494a1c85e5c3fe0ea74e321dae37846"}]},{"name":"account-baseline-security","children":[{"name":"README.md","path":"examples/account-baseline-security/README.md","sha":"367b32c66414f554edafd03d43375b58b7dafd26"},{"name":"main.tf","path":"examples/account-baseline-security/main.tf","sha":"b50cb19c57bd0917947f4f2025c9186ae38abaf1"},{"name":"outputs.tf","path":"examples/account-baseline-security/outputs.tf","sha":"e665d258e992d13639dee123987a8fe2751f29f6"},{"name":"variables.tf","path":"examples/account-baseline-security/variables.tf","sha":"158e8813f385a7aa73a2020bb51b619465eb5ed6"}]},{"name":"auto-update","children":[{"name":"README.md","path":"examples/auto-update/README.md","sha":"d7c630c4585bad7869d55bc6c62fca248eeb521a"},{"name":"auto-update-example.json","path":"examples/auto-update/auto-update-example.json","sha":"cafac0a781f8c675338226eee4b2413f5a4e88c1"}]},{"name":"aws-config-multi-region","children":[{"name":"README.md","path":"examples/aws-config-multi-region/README.md","sha":"5d472db5cdc843b494852a062d8c0880f246fcd0"},{"name":"terraform","children":[{"name":"main.tf","path":"examples/aws-config-multi-region/terraform/main.tf","sha":"cc57ea712f949d2a662c88c4ecaa508a6d0d0d4a"},{"name":"outputs.tf","path":"examples/aws-config-multi-region/terraform/outputs.tf","sha":"77ee90f69634c965b8ebed79a8d3afd6adca4db4"},{"name":"variables.tf","path":"examples/aws-config-multi-region/terraform/variables.tf","sha":"3e221cbb00cee8aac29b72000274165c3d66e17a"}]},{"name":"terragrunt","children":[{"name":"terragrunt.hcl","path":"examples/aws-config-multi-region/terragrunt/terragrunt.hcl","sha":"52e0367bbff5ce3ee7375dbe8fd74951f045264f"}]}]},{"name":"aws-config","children":[{"name":"README.md","path":"examples/aws-config/README.md","sha":"becfeb3fe2afee81cad4476fd1300a5f26566e7e"},{"name":"main.tf","path":"examples/aws-config/main.tf","sha":"d07263ccd6a96cfbae8dd25fc40c48a364b06f04"},{"name":"outputs.tf","path":"examples/aws-config/outputs.tf","sha":"ddd32698f39772d663a2d9b8a6276260f5431068"},{"name":"vars.tf","path":"examples/aws-config/vars.tf","sha":"da45a27ea7860a35e0547a0b89595e9390954d40"}]},{"name":"aws-organizations-config-rules","children":[{"name":"README.md","path":"examples/aws-organizations-config-rules/README.md","sha":"ce4f53fc37936aec55b2a7e8f358378032dac0d7"},{"name":"main.tf","path":"examples/aws-organizations-config-rules/main.tf","sha":"1dae398d8ed745e3b103f3803b887e61daf7a600"},{"name":"outputs.tf","path":"examples/aws-organizations-config-rules/outputs.tf","sha":"4319400eb4190f58458f2dd9398225869ff08da3"},{"name":"variables.tf","path":"examples/aws-organizations-config-rules/variables.tf","sha":"c97f8c6bdaf4ab3f9e5f26332fc7ec983e881a53"}]},{"name":"aws-organizations","children":[{"name":"README.md","path":"examples/aws-organizations/README.md","sha":"1da3c2fc061fee6ee99564b8b2323ccf69f2c690"},{"name":"main.tf","path":"examples/aws-organizations/main.tf","sha":"7339da612ebccaa785820b0f1e6fb42d5f72e20a"},{"name":"outputs.tf","path":"examples/aws-organizations/outputs.tf","sha":"88ba8f4012111036775958d7dfad4eec6bf84be6"},{"name":"variables.tf","path":"examples/aws-organizations/variables.tf","sha":"59afc28c87bc3c49d11c6faf7e112643f0a95481"}]},{"name":"cloudtrail","children":[{"name":"README.md","path":"examples/cloudtrail/README.md","sha":"a99ca684008a985ba9246e21d480d5aadd8a63bf"},{"name":"main.tf","path":"examples/cloudtrail/main.tf","sha":"68df53c2b732e5febd5c5c5b06f1ba5330565095"},{"name":"outputs.tf","path":"examples/cloudtrail/outputs.tf","sha":"874c4bb56d8c5841ae5d23a14e8572aab2d4adea"},{"name":"vars.tf","path":"examples/cloudtrail/vars.tf","sha":"d760a1693fc326552b1a00a24eb9deb4fb1a0af3"}]},{"name":"cross-account-iam-roles","children":[{"name":"README.md","path":"examples/cross-account-iam-roles/README.md","sha":"e29b220abacd7b0ac30a9b30ae15014936e5fc9c"},{"name":"main.tf","path":"examples/cross-account-iam-roles/main.tf","sha":"6c3469ebb3be0666378962f57fb4c8055a1cb565"},{"name":"outputs.tf","path":"examples/cross-account-iam-roles/outputs.tf","sha":"459bd44da733bb20e65e17b4e13505c03bb109b7"},{"name":"vars.tf","path":"examples/cross-account-iam-roles/vars.tf","sha":"6e707ac515c0d83d32f8dccbfcfe22c66968351a"}]},{"name":"custom-iam-entity","children":[{"name":"README.md","path":"examples/custom-iam-entity/README.md","sha":"262e2508f648ec95f6bfd32626fbb2d887cfa988"},{"name":"main.tf","path":"examples/custom-iam-entity/main.tf","sha":"c1b2291bb49e98b1b4ac642920751f54bd59c2a3"},{"name":"outputs.tf","path":"examples/custom-iam-entity/outputs.tf","sha":"835eb64f431386925438cb2f63e48e413faee90c"},{"name":"vars.tf","path":"examples/custom-iam-entity/vars.tf","sha":"4af8f352ddc35352243f8e1ac0dd3fb50f230e11"}]},{"name":"fail2ban","children":[{"name":"README.md","path":"examples/fail2ban/README.md","sha":"7f6b797884ac148c0e34fd6da0eb8224e2255d8a"},{"name":"fail2ban-example.json","path":"examples/fail2ban/fail2ban-example.json","sha":"dca42add6036b1e18f03aaa3f41c500b8767f31d"}]},{"name":"guardduty","children":[{"name":"README.md","path":"examples/guardduty/README.md","sha":"23c75950a1b8b33286b79bd5e9d853cee02d62ea"},{"name":"main.tf","path":"examples/guardduty/main.tf","sha":"c61ad567d527732db435f2d1b62c4a609c3fac1d"},{"name":"outputs.tf","path":"examples/guardduty/outputs.tf","sha":"24b4eecc8136725bafa182f1c4febdf90da49a92"},{"name":"variables.tf","path":"examples/guardduty/variables.tf","sha":"77f3fbbeef3500c93b55899ad8e92f44420858ee"}]},{"name":"iam-groups","children":[{"name":"README.md","path":"examples/iam-groups/README.md","sha":"019d8b433629eb895603e9b4d507b0bf479c3da5"},{"name":"main.tf","path":"examples/iam-groups/main.tf","sha":"3ef8b57b70f9f7f69a619749ce74430888bacebe"},{"name":"outputs.tf","path":"examples/iam-groups/outputs.tf","sha":"2901c51756a4b5d3ce1b040ff006849997650bb0"},{"name":"vars.tf","path":"examples/iam-groups/vars.tf","sha":"6faf555dda270505308f15b6fd779cdb2641b2b5"}]},{"name":"iam-user-password-policy","children":[{"name":"README.md","path":"examples/iam-user-password-policy/README.md","sha":"0af47723266b57ee39d55d74127ce0c8d902c466"},{"name":"main.tf","path":"examples/iam-user-password-policy/main.tf","sha":"ae22f0ac3173d5c0f191ec537725ea6230962fc5"},{"name":"vars.tf","path":"examples/iam-user-password-policy/vars.tf","sha":"fcdc47d795f3e20427b615e26ea2d60db7109a78"}]},{"name":"iam-users","children":[{"name":"README.md","path":"examples/iam-users/README.md","sha":"f8b65e9756e9f8c8703a854c1363be700b5fe8d9"},{"name":"main.tf","path":"examples/iam-users/main.tf","sha":"d3edb256b4ff77cd3acee71561f1ca95db8b0172"},{"name":"outputs.tf","path":"examples/iam-users/outputs.tf","sha":"5c7e14248dcd792771f5956d6acc4cd2562887b5"},{"name":"variables.tf","path":"examples/iam-users/variables.tf","sha":"5c27b34c5b14c9222e196441c29576eed1f9fb31"}]},{"name":"ip-lockdown","children":[{"name":"README.md","path":"examples/ip-lockdown/README.md","sha":"3962ba23a76d8f02e5c0ffc8cb71196991628e38"},{"name":"aws-example","children":[{"name":"README.md","path":"examples/ip-lockdown/aws-example/README.md","sha":"282005cb1cbc63ff7a642bac388a48d6cc3a2087"},{"name":"main.tf","path":"examples/ip-lockdown/aws-example/main.tf","sha":"948172240196c610e26957ca60640191fdfab0ad"},{"name":"outputs.tf","path":"examples/ip-lockdown/aws-example/outputs.tf","sha":"a175a78c9a10f9f2fd9d7c84f9b304aebc1bdb41"},{"name":"user-data","children":[{"name":"user-data.sh","path":"examples/ip-lockdown/aws-example/user-data/user-data.sh","sha":"c6d308027737a434f4c96bc3eba5bd301897af62"}]},{"name":"vars.tf","path":"examples/ip-lockdown/aws-example/vars.tf","sha":"0db59e9a6307fa940ddf5258130be1c9504c86a5"}]},{"name":"ip-lockdown-sample.json","path":"examples/ip-lockdown/ip-lockdown-sample.json","sha":"2ccf2fe1a5b90bf4ab760ddd4f7714a8e1d43df6"},{"name":"local-test","children":[{"name":"README.md","path":"examples/ip-lockdown/local-test/README.md","sha":"3f0e1a6483ce3155bb04dbb9a4fd76ed41486d35"},{"name":"docker-compose.yml","path":"examples/ip-lockdown/local-test/docker-compose.yml","sha":"7c8e3a5d1fd40a95ef99b4bba0911c63ed43b530"}]}]},{"name":"kms-master-key-multi-region","children":[{"name":"main.tf","path":"examples/kms-master-key-multi-region/main.tf","sha":"2f92868a8786cfedfc5e431170382d6840b4ae21"},{"name":"outputs.tf","path":"examples/kms-master-key-multi-region/outputs.tf","sha":"c2685a282b5ce295c2dd80a78841711a40e80dcb"},{"name":"variables.tf","path":"examples/kms-master-key-multi-region/variables.tf","sha":"411c8eb05ec9dc713094e992f214c13dd05482fc"}]},{"name":"kms-master-key","children":[{"name":"README.md","path":"examples/kms-master-key/README.md","sha":"888367af686e25e12f987a100d9d593bc6ca71cc"},{"name":"main.tf","path":"examples/kms-master-key/main.tf","sha":"36e66561c53a74f0c66813237d92c83c2338d46d"},{"name":"outputs.tf","path":"examples/kms-master-key/outputs.tf","sha":"4d5fd0a19ea917beff0241f169b51417ff9935b9"},{"name":"vars.tf","path":"examples/kms-master-key/vars.tf","sha":"d16a2f28e5d87a9e75191158994d7cf0b3c4bff1"}]},{"name":"ntp","children":[{"name":"README.md","path":"examples/ntp/README.md","sha":"b676e802c1d196f6af204d14d143b80864bccd30"},{"name":"ntp-example.json","path":"examples/ntp/ntp-example.json","sha":"ab322bfd9042a9eaf3a9b2ec3418abd7188bc99a"}]},{"name":"os-hardening","children":[{"name":"README.md","path":"examples/os-hardening/README.md","sha":"2518516d2aea0bc3f8d142f0ee8db181ab491d6e"},{"name":"packer-build.sh","path":"examples/os-hardening/packer-build.sh","sha":"7a35196064d70b06cd349d80b64a82b0affe18f0"},{"name":"packer","children":[{"name":"amazon-linux.json","path":"examples/os-hardening/packer/amazon-linux.json","sha":"e75442792ba2588a02bcc93a90eceade50e5a846"},{"name":"files","children":[{"name":"etc","children":[{"name":"fstab","path":"examples/os-hardening/packer/files/etc/fstab","sha":"cbf68cec68a92bc54f514dd0d6906f19cea857e6"}]}]}]},{"name":"terraform","children":[{"name":"main.tf","path":"examples/os-hardening/terraform/main.tf","sha":"0279c513bb48e2a5c966b19298066c04bf6b02f5"},{"name":"outputs.tf","path":"examples/os-hardening/terraform/outputs.tf","sha":"33083aed25a4ed6e323bf84381b896614814c9d1"},{"name":"vars.tf","path":"examples/os-hardening/terraform/vars.tf","sha":"60e4d2707d2f9edba702c9e8edd48ecfc30ae514"}]}]},{"name":"saml-iam-roles","children":[{"name":"README.md","path":"examples/saml-iam-roles/README.md","sha":"e316aefb1fbf753baa8625c8063e239c799c52b3"},{"name":"main.tf","path":"examples/saml-iam-roles/main.tf","sha":"d0ed7822a55913c6c93391ee345b32a8912ee3ae"},{"name":"outputs.tf","path":"examples/saml-iam-roles/outputs.tf","sha":"1bd4fec9529cddfd2d3f61bba60f9dfb8b286c70"},{"name":"saml-metadata.xml","path":"examples/saml-iam-roles/saml-metadata.xml","sha":"88596cfde52242a43559c79216a1c60b2ea12903"},{"name":"vars.tf","path":"examples/saml-iam-roles/vars.tf","sha":"8673df83c8d53eadd579d9ac9ae536711561c746"}]},{"name":"ssh-grunt","children":[{"name":"houston","children":[{"name":"README.md","path":"examples/ssh-grunt/houston/README.md","sha":"ac5cb5fd6c2b55bf198ec4a9ec744d7070bf1875"},{"name":"main.tf","path":"examples/ssh-grunt/houston/main.tf","sha":"259871d0103ff1bfd7e3e3a23147a0325e3600a1"},{"name":"outputs.tf","path":"examples/ssh-grunt/houston/outputs.tf","sha":"978b316044d417393b70100a427de1068c4d417f"},{"name":"vars.tf","path":"examples/ssh-grunt/houston/vars.tf","sha":"34c542e9e1afc5dca29476a6ca40d27050aa02d2"}]},{"name":"iam","children":[{"name":"README.md","path":"examples/ssh-grunt/iam/README.md","sha":"d79ebb115ab2452ff3e3dfe57c893e319ffd05ab"},{"name":"main.tf","path":"examples/ssh-grunt/iam/main.tf","sha":"334d8b8f5b840b3946da954bd4e753c3d9011b42"},{"name":"outputs.tf","path":"examples/ssh-grunt/iam/outputs.tf","sha":"978b316044d417393b70100a427de1068c4d417f"},{"name":"vars.tf","path":"examples/ssh-grunt/iam/vars.tf","sha":"093c5c41394e22b8308abc432b610a87b75e7680"}]},{"name":"mock-houston","children":[{"name":"README.md","path":"examples/ssh-grunt/mock-houston/README.md","sha":"94c0ef92814db64b5f3d578a4ba7011fb058fedf"},{"name":"main.tf","path":"examples/ssh-grunt/mock-houston/main.tf","sha":"5d095152e7efc51db2d2a2c25a96e6237588c538"},{"name":"outputs.tf","path":"examples/ssh-grunt/mock-houston/outputs.tf","sha":"a25069b6b919c0fa31fc32c3bcf1d326f7c3d46c"},{"name":"vars.tf","path":"examples/ssh-grunt/mock-houston/vars.tf","sha":"984df0c1fa7e7c78d8755652c321dcd06543d030"}]},{"name":"packer","children":[{"name":"README.md","path":"examples/ssh-grunt/packer/README.md","sha":"40dc203c7287544434c7f668ea58782afd2f2386"},{"name":"build-binary.sh","path":"examples/ssh-grunt/packer/build-binary.sh","sha":"6e96bfaa2b82f54ed3f1c5ffb8bb3ee0f99055e4"},{"name":"ssh-grunt-houston.json","path":"examples/ssh-grunt/packer/ssh-grunt-houston.json","sha":"cd3c4a1c2053c238720b0b4111efc3003db7e6cb"},{"name":"ssh-grunt-iam.json","path":"examples/ssh-grunt/packer/ssh-grunt-iam.json","sha":"ab7237cf73deccb4f94837046be2efa0d6df3ebf"}]}]},{"name":"ssm-healthchecks-iam-permissions","children":[{"name":"README.md","path":"examples/ssm-healthchecks-iam-permissions/README.md","sha":"f1fe555a3aff887a966def0a1d3ccaff3dd826e7"},{"name":"main.tf","path":"examples/ssm-healthchecks-iam-permissions/main.tf","sha":"2ff78d1f7cc4a484319a74a62880b26ad679f8b5"},{"name":"outputs.tf","path":"examples/ssm-healthchecks-iam-permissions/outputs.tf","sha":"52688c3a4f1f8349500505fb8949fa0d21c385a3"},{"name":"vars.tf","path":"examples/ssm-healthchecks-iam-permissions/vars.tf","sha":"3fb4df876ccbcd8a3ff3af79efaf3479a74261bf"}]}]},{"name":"modules","children":[{"name":"_deprecated","children":[{"name":"custom-iam-group","children":[{"name":"README.md","path":"modules/_deprecated/custom-iam-group/README.md","sha":"e7a0ff783eb1052aa77fe50d7eaa6a06d2d82649"}]}]},{"name":"account-baseline-app","children":[{"name":"README.adoc","path":"modules/account-baseline-app/README.adoc","sha":"7f18ec7d53555ca35cb437e748ad46886f5995aa"},{"name":"main.tf","path":"modules/account-baseline-app/main.tf","sha":"5eb628e0d89efd6584ad2197602de3f294b442e8"},{"name":"outputs.tf","path":"modules/account-baseline-app/outputs.tf","sha":"594fb9203a103467f65ad927002970c93e09d9c5"},{"name":"variables.tf","path":"modules/account-baseline-app/variables.tf","sha":"0ddbe33bc40bf9de40f60fe215ff1c05cb8853ac"}]},{"name":"account-baseline-root","children":[{"name":"README.adoc","path":"modules/account-baseline-root/README.adoc","sha":"3726568b9ec7c5704cb2067a6136e28d88e4c159"},{"name":"main.tf","path":"modules/account-baseline-root/main.tf","sha":"701c7246b061715bc4e86af6f3c439dc37b07fd0"},{"name":"outputs.tf","path":"modules/account-baseline-root/outputs.tf","sha":"a9f9631087de4f9d0e0e3a42df080783aef9bd86"},{"name":"variables.tf","path":"modules/account-baseline-root/variables.tf","sha":"e42b3bc57cacabdfb0b384c88fb07a0221b66f4c"}]},{"name":"account-baseline-security","children":[{"name":"README.adoc","path":"modules/account-baseline-security/README.adoc","sha":"4a6ff36ad488396075f61c9e8c01ef16d2d4656d"},{"name":"main.tf","path":"modules/account-baseline-security/main.tf","sha":"154efbb9d9f408dc40f7f2f80917c0de2e1d3e7f"},{"name":"outputs.tf","path":"modules/account-baseline-security/outputs.tf","sha":"0f533af6c3ac863517873ca79bb972591a930cbf"},{"name":"variables.tf","path":"modules/account-baseline-security/variables.tf","sha":"a5ddcfa1d79474a57093ddcad32d4458d86488f5"}]},{"name":"auto-update","children":[{"name":"README.adoc","path":"modules/auto-update/README.adoc","sha":"6aefe0ec50a3479dc08366ee6ace6f306eec8e7a"},{"name":"core-concepts.md","path":"modules/auto-update/core-concepts.md","sha":"a292e900ff20e205679c5a8a2b382081f338a41f"},{"name":"install-scripts","children":[{"name":"configure-auto-update","path":"modules/auto-update/install-scripts/configure-auto-update","sha":"9557efec90bf62cbcd0360198ec2bf984a8a873b"},{"name":"unattended_upgrades_config.txt","path":"modules/auto-update/install-scripts/unattended_upgrades_config.txt","sha":"abe88fd8a5037ce518bec69a6cac0699cb421d47"},{"name":"yum_cron_config.txt","path":"modules/auto-update/install-scripts/yum_cron_config.txt","sha":"e7ef4273f1b2af0c9c032fadaacd03130ba5ea78"}]},{"name":"install.sh","path":"modules/auto-update/install.sh","sha":"7c19fd0d04b11c358af64149b3169d6b2c5e3b58"}]},{"name":"aws-auth","children":[{"name":"AWS-AUTH-LASTPASS.md","path":"modules/aws-auth/AWS-AUTH-LASTPASS.md","sha":"f989822c9600fdb7dec2b67a929f8e4b49947aa8"},{"name":"README.md","path":"modules/aws-auth/README.md","sha":"334b60630b57378a8327981cc6581244a55c2e24"},{"name":"bin","children":[{"name":"aws-auth","path":"modules/aws-auth/bin/aws-auth","sha":"973c0ad62b2ab51cb18abf57d332869171480eff"}]},{"name":"install.sh","path":"modules/aws-auth/install.sh","sha":"ab9611d92d6822ceed981bdff3766724366037f0"}]},{"name":"aws-config-multi-region","children":[{"name":"README.adoc","path":"modules/aws-config-multi-region/README.adoc","sha":"8f95c4e964a5a0f913139f1a8d3f3d31345e9c06"},{"name":"images","children":[{"name":"aws-config-architecture.png","path":"modules/aws-config-multi-region/images/aws-config-architecture.png","sha":"721458048d5e539468c438498863a91fa96e0a85"}]},{"name":"main.tf","path":"modules/aws-config-multi-region/main.tf","sha":"ff0b6560a60e97b011c28c63f532f87d82d8b310"},{"name":"outputs.tf","path":"modules/aws-config-multi-region/outputs.tf","sha":"b0b62c8a003fcef88734cb540ad9e75b25721ffa"},{"name":"variables.tf","path":"modules/aws-config-multi-region/variables.tf","sha":"9fe96d49af6b90e85301b9ffcd7278bf863e1580"}]},{"name":"aws-config","children":[{"name":"README.adoc","path":"modules/aws-config/README.adoc","sha":"dee8d8a1ccfe87003d2bcea8d9446a9d74dbc64a"},{"name":"core-concepts.md","path":"modules/aws-config/core-concepts.md","sha":"7f917cedb2e054a6e7ac4455a92240ff54f15987"},{"name":"main.tf","path":"modules/aws-config/main.tf","sha":"5289849ade1935b3702e1e2ef5462084015d583e"},{"name":"outputs.tf","path":"modules/aws-config/outputs.tf","sha":"8c8c3d4c9fd8d408d34cda20b4302abc6401005b"},{"name":"vars.tf","path":"modules/aws-config/vars.tf","sha":"33407d204d241be3fab6310757fb912629ebbf79"}]},{"name":"aws-organizations-config-rules","children":[{"name":"README.adoc","path":"modules/aws-organizations-config-rules/README.adoc","sha":"bec4b2e3f116e356bbe7776c28f27002c838e61a"},{"name":"core-concepts.md","path":"modules/aws-organizations-config-rules/core-concepts.md","sha":"28f0d3a3325c97e0417c01671bbfc8a1b577498a"},{"name":"main.tf","path":"modules/aws-organizations-config-rules/main.tf","sha":"c67d58ca43acafce5f464b969980074631573490"},{"name":"outputs.tf","path":"modules/aws-organizations-config-rules/outputs.tf","sha":"9b78cd00ad242a02579147b390c6ad946620e1f0"},{"name":"variables.tf","path":"modules/aws-organizations-config-rules/variables.tf","sha":"1d8616a01e1db2c0672827920afef50d921fde6d"}]},{"name":"aws-organizations","children":[{"name":"README.adoc","path":"modules/aws-organizations/README.adoc","sha":"711b480a00245dc87a73e1c13a18867498eb6f7b"},{"name":"core-concepts.md","path":"modules/aws-organizations/core-concepts.md","sha":"8766c8f36eef9e8992bf13a44f6571261c43995d"},{"name":"main.tf","path":"modules/aws-organizations/main.tf","sha":"d835568c2c09a220fba9e85e306b276ab8d894b5"},{"name":"outputs.tf","path":"modules/aws-organizations/outputs.tf","sha":"5d71fce583011b7351615821e6a888eb8f73906a"},{"name":"variables.tf","path":"modules/aws-organizations/variables.tf","sha":"4eac97565d5ab76a5e0c03cde4a9337001125156"}]},{"name":"cloudtrail","children":[{"name":"README.adoc","path":"modules/cloudtrail/README.adoc","sha":"cb56736b0eff0b10521fc5a42e6fd30e6660f165"},{"name":"core-concepts.md","path":"modules/cloudtrail/core-concepts.md","sha":"c5f894e0f3d2f9d66349b13cc9daecd97a370070","toggled":true},{"name":"main.tf","path":"modules/cloudtrail/main.tf","sha":"4708aff79685eb0e15130e31930ae86c02494634"},{"name":"outputs.tf","path":"modules/cloudtrail/outputs.tf","sha":"20e598a564e2362f8e199d710699dedded900dfb"},{"name":"vars.tf","path":"modules/cloudtrail/vars.tf","sha":"f691aeb8561ee007e9a78bbbd8bf14e1294d3b7f"}],"toggled":true},{"name":"cross-account-iam-roles","children":[{"name":"README.md","path":"modules/cross-account-iam-roles/README.md","sha":"3f1dfc8e46aa4b758a5970f4305b2c443bf692ef"},{"name":"main.tf","path":"modules/cross-account-iam-roles/main.tf","sha":"d4b66fff9f7acee9999f6674a86441e09ca9b393"},{"name":"outputs.tf","path":"modules/cross-account-iam-roles/outputs.tf","sha":"73b26ff9804cb98404c81fa07e084042898482cf"},{"name":"vars.tf","path":"modules/cross-account-iam-roles/vars.tf","sha":"9a45fb999b66e057a1f23d2457c130963b7ddbdc"}]},{"name":"custom-iam-entity","children":[{"name":"README.md","path":"modules/custom-iam-entity/README.md","sha":"98ab8129418c43978d46d58896b6e64172995aba"},{"name":"main.tf","path":"modules/custom-iam-entity/main.tf","sha":"f520be8f0e233548111365316c24d3bc7491cad0"},{"name":"outputs.tf","path":"modules/custom-iam-entity/outputs.tf","sha":"23cc0eb151da4ab2f146c89d9ad53dfc0e5c8c82"},{"name":"vars.tf","path":"modules/custom-iam-entity/vars.tf","sha":"ad93fc85d6d7c21bb348086a72406f08ccd07edb"}]},{"name":"fail2ban","children":[{"name":"README.md","path":"modules/fail2ban/README.md","sha":"2301349c1b8775809b7362189a72655ce58b26fb"},{"name":"install-scripts","children":[{"name":"cloudwatch-metric.conf","path":"modules/fail2ban/install-scripts/cloudwatch-metric.conf","sha":"f78f5f55f585a6efe60a51a2c0f41e4a63f99749"},{"name":"configure-fail2ban","path":"modules/fail2ban/install-scripts/configure-fail2ban","sha":"2d44d0459dbbcc9a1d2747648875a1ab44d7548f"},{"name":"fail2ban.local","path":"modules/fail2ban/install-scripts/fail2ban.local","sha":"8292c4a18c825bfbf0a8d52cfb2746aa43f76ca4"},{"name":"filters.sshd.amazon.conf","path":"modules/fail2ban/install-scripts/filters.sshd.amazon.conf","sha":"093bb1baf88a1e283a43b7dd7d04c64992abecc6"},{"name":"jail.amazon.local","path":"modules/fail2ban/install-scripts/jail.amazon.local","sha":"a0aef73873e461c46ff63a4a3e5166ad3453c5e3"},{"name":"jail.amazon2.local","path":"modules/fail2ban/install-scripts/jail.amazon2.local","sha":"7f0c82cc3e4f5e3e569f8bb902164f7dbd6a3dee"},{"name":"jail.ubuntu.local","path":"modules/fail2ban/install-scripts/jail.ubuntu.local","sha":"148543b26f543c3e37434736fba7d484ad176804"}]},{"name":"install.sh","path":"modules/fail2ban/install.sh","sha":"8f7b536f08506dabc2f6beb6cd5a50f7282168aa"},{"name":"user-data-scripts","children":[{"name":"configure-fail2ban-cloudwatch.sh","path":"modules/fail2ban/user-data-scripts/configure-fail2ban-cloudwatch.sh","sha":"64b7c27b8aa50302f4f7e35ebd8bbf93064bb777"}]}]},{"name":"guardduty-multi-region","children":[{"name":"README.adoc","path":"modules/guardduty-multi-region/README.adoc","sha":"0c0833b9655d1d292f086b8f27c594ef1b968d68"},{"name":"main.tf","path":"modules/guardduty-multi-region/main.tf","sha":"861d5b2287f4594c690a251b72d9549c59b9d1ad"},{"name":"outputs.tf","path":"modules/guardduty-multi-region/outputs.tf","sha":"17ed87f6be722742d29aee0ef8e35a641a2ea54e"},{"name":"variables.tf","path":"modules/guardduty-multi-region/variables.tf","sha":"992199e9e968a3006918b286c7f3e69eb2fbbd74"}]},{"name":"guardduty","children":[{"name":"README.adoc","path":"modules/guardduty/README.adoc","sha":"8826f32664593d0cdc0ff4a7fd94e5cbf475478a"},{"name":"core-concepts.md","path":"modules/guardduty/core-concepts.md","sha":"2eab0fd6c0548ba11104b6d778eb224df5622886"},{"name":"main.tf","path":"modules/guardduty/main.tf","sha":"37cfa8a2a9c13d7ee6f9227af08981f60c90a318"},{"name":"outputs.tf","path":"modules/guardduty/outputs.tf","sha":"0fd6fdc76d8bc1bb4c544028c802248999d309f7"},{"name":"variables.tf","path":"modules/guardduty/variables.tf","sha":"e5c1e4b60f219d93e21a382bb3dad970977c9fcf"}]},{"name":"iam-groups","children":[{"name":"README.md","path":"modules/iam-groups/README.md","sha":"072baead8ab54d99d6c9232802c42522a9785c96"},{"name":"_docs","children":[{"name":"iam-user-access-to-billing.png","path":"modules/iam-groups/_docs/iam-user-access-to-billing.png","sha":"063f6cf8dc766b4d44942de89660e8ab9e1f3d63"},{"name":"my-account.png","path":"modules/iam-groups/_docs/my-account.png","sha":"387320200ed756ce4191afef87f0ab76e2c3d89a"}]},{"name":"main.tf","path":"modules/iam-groups/main.tf","sha":"ac1e4b8ccc9136f3fe130c0ff14f6fc759f76f46"},{"name":"outputs.tf","path":"modules/iam-groups/outputs.tf","sha":"749f97fe15adef5db5386fad10fde29f0e65adea"},{"name":"variables.tf","path":"modules/iam-groups/variables.tf","sha":"17de211213e967465c73d89e2d630cd81a491c66"}]},{"name":"iam-policies","children":[{"name":"README.md","path":"modules/iam-policies/README.md","sha":"39046a8e1484064e3c544fd10de13792733fea9e"},{"name":"main.tf","path":"modules/iam-policies/main.tf","sha":"f40515e3801379d0b0965d92a186299f226d7ff8"},{"name":"outputs.tf","path":"modules/iam-policies/outputs.tf","sha":"e6cdfd3ab5536301578b48c6b171da0ae71b07e0"},{"name":"vars.tf","path":"modules/iam-policies/vars.tf","sha":"9bb0c72feffffb65d61a2ed537359e06bd0c3d2b"}]},{"name":"iam-user-password-policy","children":[{"name":"README.md","path":"modules/iam-user-password-policy/README.md","sha":"5bea6ba56fc796be5b860549156a3a251735fc2a"},{"name":"main.tf","path":"modules/iam-user-password-policy/main.tf","sha":"9670fa0991057e03a72b72987c02a71e14611724"},{"name":"vars.tf","path":"modules/iam-user-password-policy/vars.tf","sha":"7c08eef88a7b13226cc4e18aa8338db64fdf83f0"}]},{"name":"iam-users","children":[{"name":"README.md","path":"modules/iam-users/README.md","sha":"9da56f1341cc4b4dc67038391ea8f52198bb3b21"},{"name":"main.tf","path":"modules/iam-users/main.tf","sha":"0a1fd72295d0db73ae91cb96811342a3cf7d0447"},{"name":"outputs.tf","path":"modules/iam-users/outputs.tf","sha":"e4095403bfd60328c76b192c4b5583602d8969d0"},{"name":"variables.tf","path":"modules/iam-users/variables.tf","sha":"8145ff6074f12d753b343ac9ed37962ca0c5410d"}]},{"name":"ip-lockdown","children":[{"name":"README.md","path":"modules/ip-lockdown/README.md","sha":"af806e396600aed64922eac8a3c7ab29a90f858d"},{"name":"install.sh","path":"modules/ip-lockdown/install.sh","sha":"ce61af763bee9ad29754220ae24521f22c3a956f"},{"name":"ip-lockdown","path":"modules/ip-lockdown/ip-lockdown","sha":"93a0e1f5876e7de5778c595e8801d64986cb118b"}]},{"name":"kms-master-key-multi-region","children":[{"name":"README.adoc","path":"modules/kms-master-key-multi-region/README.adoc","sha":"0e7764d5d98f2cc2f5decd6429ca3de22d4bed87"},{"name":"main.tf","path":"modules/kms-master-key-multi-region/main.tf","sha":"762497cf4fd073a47e5aa144dca0d7fe3575ba11"},{"name":"outputs.tf","path":"modules/kms-master-key-multi-region/outputs.tf","sha":"932a3ac2a94e4950267c55c115f1118328345bf3"},{"name":"variables.tf","path":"modules/kms-master-key-multi-region/variables.tf","sha":"275c4784a01a704089fe9f7268161ad167082a4d"}]},{"name":"kms-master-key","children":[{"name":"README.md","path":"modules/kms-master-key/README.md","sha":"8dfd4d4425c1c69f529e3965629738506a3dd2c1"},{"name":"main.tf","path":"modules/kms-master-key/main.tf","sha":"c082c7479b4419bbb9f66f7d500914c8af7ccb65"},{"name":"outputs.tf","path":"modules/kms-master-key/outputs.tf","sha":"4d0dbba81e8186243d96a8325a5f643d87543451"},{"name":"vars.tf","path":"modules/kms-master-key/vars.tf","sha":"6eeb738adff0d3e793cd6f8d1a0217fe1772ef92"}]},{"name":"ntp","children":[{"name":"README.md","path":"modules/ntp/README.md","sha":"c81ae3adf4d5af364729c5537414de1ada470af5"},{"name":"install.sh","path":"modules/ntp/install.sh","sha":"66f01538550459e770dde3d03b8c1ee705301b49"}]},{"name":"os-hardening","children":[{"name":"README.md","path":"modules/os-hardening/README.md","sha":"3e864b0e9208eb6809adf41968c51e02fc233ee1"},{"name":"_docs","children":[{"name":"Helpful Email.md","path":"modules/os-hardening/_docs/Helpful Email.md","sha":"246a0b80b29f5ff3d2b2f4c5c170fc927e2d9dd7"}]},{"name":"ami-builder","children":[{"name":"files","children":[{"name":"user-data.sh.template","path":"modules/os-hardening/ami-builder/files/user-data.sh.template","sha":"4a3c87a19e1a4caa20b9b425b2a02101566d1166"}]},{"name":"main.tf","path":"modules/os-hardening/ami-builder/main.tf","sha":"3b23018276920ce33dab358eab79ef39e269fd98"},{"name":"outputs.tf","path":"modules/os-hardening/ami-builder/outputs.tf","sha":"8ce2ee598124ca50dd530a33aa60f5d1452a4a2b"},{"name":"vars.tf","path":"modules/os-hardening/ami-builder/vars.tf","sha":"c5927cfcebf6781b8b920d8fd7872f2992bb1501"}]},{"name":"partition-scripts","children":[{"name":"README.md","path":"modules/os-hardening/partition-scripts/README.md","sha":"a2986f1ab8f7470d2ba71d5270e5217d64cb10a3"},{"name":"bin","children":[{"name":"cleanup-volume","path":"modules/os-hardening/partition-scripts/bin/cleanup-volume","sha":"c7cbf3ecebd915235238557d27a1ce25e6fc10fa"},{"name":"partition-volume","path":"modules/os-hardening/partition-scripts/bin/partition-volume","sha":"f4f8566a1ef6aa4ff0c0268bd28721488aa6dfc4"}]},{"name":"install.sh","path":"modules/os-hardening/partition-scripts/install.sh","sha":"606776c068260836e8612a681ff4e3edc8abdb41"}]}]},{"name":"saml-iam-roles","children":[{"name":"README.md","path":"modules/saml-iam-roles/README.md","sha":"fed1904b6d61d7d3fdee2931cfeb0cb79ec54523"},{"name":"main.tf","path":"modules/saml-iam-roles/main.tf","sha":"3bcda8409409f76febb78ce378e207ec1221bf83"},{"name":"outputs.tf","path":"modules/saml-iam-roles/outputs.tf","sha":"b2778906a16b2b513808aaea58c06cc3c9fc8c42"},{"name":"vars.tf","path":"modules/saml-iam-roles/vars.tf","sha":"981970525d6fd88bbaad9e72745f390795102333"}]},{"name":"ssh-grunt-selinux-policy","children":[{"name":"README.md","path":"modules/ssh-grunt-selinux-policy/README.md","sha":"8a934c81da696e32c365183b6a707594da99ba79"},{"name":"install.sh","path":"modules/ssh-grunt-selinux-policy/install.sh","sha":"3de871d61a9990e7f2c130f23afaf00daeb6bbef"},{"name":"ssh-grunt.pp","path":"modules/ssh-grunt-selinux-policy/ssh-grunt.pp","sha":"7c7050f812cd0e3cb34e37b88c35fb09f369be7d"},{"name":"ssh-grunt.te","path":"modules/ssh-grunt-selinux-policy/ssh-grunt.te","sha":"3317a71feaa633662a00b1dc05b1176cb85c9793"}]},{"name":"ssh-grunt","children":[{"name":".dockerignore","path":"modules/ssh-grunt/.dockerignore","sha":"a725465aee245635a2bd129af54858ed32c84cb8"},{"name":"Dockerfile","path":"modules/ssh-grunt/Dockerfile","sha":"3d1a6eb67de35573d8ec48bb6ac06b515f9a63d8"},{"name":"README.adoc","path":"modules/ssh-grunt/README.adoc","sha":"89e1ff7db5620809af182703c45f87601e59a766"},{"name":"_ci","children":[{"name":"build-and-test.sh","path":"modules/ssh-grunt/_ci/build-and-test.sh","sha":"903993de2d7bcde19d472fa5e510ee862d4b10c3"},{"name":"test.sh","path":"modules/ssh-grunt/_ci/test.sh","sha":"235603944316e81f1da1cc0248b80beecf99cb27"}]},{"name":"_docs","children":[{"name":"houston-upload-ssh-key.png","path":"modules/ssh-grunt/_docs/houston-upload-ssh-key.png","sha":"e32519497262f9796a4ea46c53953923975cbd7d"},{"name":"iam-upload-ssh-key.png","path":"modules/ssh-grunt/_docs/iam-upload-ssh-key.png","sha":"8bb1e793185eb0b4822023552899874394342f21"}]},{"name":"core-concepts.md","path":"modules/ssh-grunt/core-concepts.md","sha":"be3b64a930906b8b16412ccdc0fe9384079a2191"},{"name":"docker-compose.yml","path":"modules/ssh-grunt/docker-compose.yml","sha":"0609cfaadf18bb9eb8ff13459cf9f0f10928765e"},{"name":"go.mod","path":"modules/ssh-grunt/go.mod","sha":"33e7bfc12450f68fe0fc800d06248129ed229b9f"},{"name":"go.sum","path":"modules/ssh-grunt/go.sum","sha":"9c21e75d8e59393633a732fe8b646daedf4ac139"},{"name":"scripts","children":[{"name":"build-linux-binary.sh","path":"modules/ssh-grunt/scripts/build-linux-binary.sh","sha":"fc74dd9990e9f4526ae2e7cd13e338d4fd0f11c4"},{"name":"run.sh","path":"modules/ssh-grunt/scripts/run.sh","sha":"050027e034cd03e53625986eb0f331c043492cf6"}]},{"name":"src","children":[{"name":"cli.go","path":"modules/ssh-grunt/src/cli.go","sha":"f72f670dcf0ae2e0bcb8ed02e91c706a5e8c3be0"},{"name":"cli_test.go","path":"modules/ssh-grunt/src/cli_test.go","sha":"89c94ffdefb2e607fa005f028bdbd13b2f6c13f0"},{"name":"collections.go","path":"modules/ssh-grunt/src/collections.go","sha":"aa9b67f00f57088f9bf4e129dcc53003524dd0a7"},{"name":"cron.go","path":"modules/ssh-grunt/src/cron.go","sha":"4ceb8efd0cdf51b5170bb152b6824fc54f8d429c"},{"name":"cron_test.go","path":"modules/ssh-grunt/src/cron_test.go","sha":"4b87577a1cc2b8dbff08457d60bbc96546149174"},{"name":"errors.go","path":"modules/ssh-grunt/src/errors.go","sha":"03c89804638ecc45fdcd0a0aeaed9ea5f605940b"},{"name":"file.go","path":"modules/ssh-grunt/src/file.go","sha":"eb991fd15ac2c3660313e6d4c5669b36ccc9cc21"},{"name":"groups.go","path":"modules/ssh-grunt/src/groups.go","sha":"49e569a80abb6306ab0f7fd79c810d2e2ad8ab3a"},{"name":"groups_test.go","path":"modules/ssh-grunt/src/groups_test.go","sha":"7e54ba9b640b07605ae959de086fc6998861e311"},{"name":"houston.go","path":"modules/ssh-grunt/src/houston.go","sha":"e9db062f2cb815b49e4df754427ae286e4d163d4"},{"name":"houston_test.go","path":"modules/ssh-grunt/src/houston_test.go","sha":"82a9b2d2d41e09b6949897ed989a483fc7e0a650"},{"name":"iam.go","path":"modules/ssh-grunt/src/iam.go","sha":"dafbc8fbb732d2d6212cade786eb13d7215b9862"},{"name":"iam_test.go","path":"modules/ssh-grunt/src/iam_test.go","sha":"79a55543a72baf93bbac7140d89226e3fd7ab133"},{"name":"logger.go","path":"modules/ssh-grunt/src/logger.go","sha":"93095ba8216709b3178fcc44a76421a765f4e302"},{"name":"main.go","path":"modules/ssh-grunt/src/main.go","sha":"a89d9402d32d371dc9b945ab9c72996808d17b85"},{"name":"shell.go","path":"modules/ssh-grunt/src/shell.go","sha":"7f49eeee4119efde0bd58d7c78fd4ef785dc5f6c"},{"name":"ssh.go","path":"modules/ssh-grunt/src/ssh.go","sha":"8e6b62d6c33279aaf5af6cabacd0afc4d186ca97"},{"name":"ssh_test.go","path":"modules/ssh-grunt/src/ssh_test.go","sha":"7500d8fd85ef74758501f6952be45cb523e29cd1"},{"name":"string.go","path":"modules/ssh-grunt/src/string.go","sha":"fc61ca9625f9d654c2b3576ff932db1b90ae9dfe"},{"name":"string_test.go","path":"modules/ssh-grunt/src/string_test.go","sha":"78bf08d239079c9c985d40da1cc9bcdcb4c0bc5d"},{"name":"sync.go","path":"modules/ssh-grunt/src/sync.go","sha":"7c2f9ff292b484a7ca1ab14e1bbd558cd24553f2"},{"name":"sync_test.go","path":"modules/ssh-grunt/src/sync_test.go","sha":"2ddb07aedec67d1698af022e4e1391ea60636f9e"},{"name":"url.go","path":"modules/ssh-grunt/src/url.go","sha":"0af5ddc5f3e27af95d6f6ddd41acf0c229962f7f"},{"name":"url_test.go","path":"modules/ssh-grunt/src/url_test.go","sha":"606974cac1eee3f309a951c1d9e11ed389088836"},{"name":"users.go","path":"modules/ssh-grunt/src/users.go","sha":"6c3a8a22006a91656fcc5fd31d684271cdf129e3"},{"name":"users_test.go","path":"modules/ssh-grunt/src/users_test.go","sha":"fdd9f7f99466c223b9abdd4951147c8febc0b3fb"}]}]},{"name":"ssh-iam","children":[{"name":"README.md","path":"modules/ssh-iam/README.md","sha":"4aa06d6a729e53384b6d2a43c06ee38807092f32"}]},{"name":"ssm-healthchecks-iam-permissions","children":[{"name":"README.md","path":"modules/ssm-healthchecks-iam-permissions/README.md","sha":"005260025ae51ed9e13f1b6c6f9d737a02d5db68"},{"name":"main.tf","path":"modules/ssm-healthchecks-iam-permissions/main.tf","sha":"6b6b91fa59bc86de7521264ff34217cc88ae3842"},{"name":"vars.tf","path":"modules/ssm-healthchecks-iam-permissions/vars.tf","sha":"731aa1c2f275f723272114ef0357a8c3a246b47e"}]},{"name":"tls-cert-private","children":[{"name":"Dockerfile","path":"modules/tls-cert-private/Dockerfile","sha":"2d8683d51957cb17ffef180dd57b43651b1e9d23"},{"name":"README.md","path":"modules/tls-cert-private/README.md","sha":"c6996ec25d7d9b1ab4f79d8164a14e86e1ac844f"},{"name":"docker-compose.yml","path":"modules/tls-cert-private/docker-compose.yml","sha":"f872026e8d51ceaab2e1c11cc9cf9c35ba81f29c"},{"name":"files","children":[{"name":"openssl.cnf","path":"modules/tls-cert-private/files/openssl.cnf","sha":"2542542c80ab180c47d3e0a27dbded65bed572de"}]},{"name":"scripts","children":[{"name":"generate-ca-keypair.sh","path":"modules/tls-cert-private/scripts/generate-ca-keypair.sh","sha":"395ee97c0e499c660efac5c5cf1f79dfcdbb69f8"},{"name":"generate-tls-keypair.sh","path":"modules/tls-cert-private/scripts/generate-tls-keypair.sh","sha":"f1c3577437fd589087704a9c003de416cb87d232"},{"name":"main.sh","path":"modules/tls-cert-private/scripts/main.sh","sha":"dc7af965ffb783bbef449010818e69294fa2ef75"}]}]}],"toggled":true},{"name":"test","children":[{"name":"README.md","path":"test/README.md","sha":"aa4847518037f1c42933d3eb162962e804223b31"},{"name":"common","children":[{"name":"test_helpers.go","path":"test/common/test_helpers.go","sha":"8c827bd32e7b60aaf95146b580b1ba8268cf9eb0"}]},{"name":"go.mod","path":"test/go.mod","sha":"253fb75ed4410699843fc1290bf5cccc2bff84f1"},{"name":"go.sum","path":"test/go.sum","sha":"11310f81f00ac31f66c1576c5f4d2051f3424d8b"},{"name":"landingzone","children":[{"name":"account_baseline_test.go","path":"test/landingzone/account_baseline_test.go","sha":"11f245532318d4408e1bbadf7e48eb50a0365066"},{"name":"aws_config_test.go","path":"test/landingzone/aws_config_test.go","sha":"530a1a5be71777981582467ff0f90e8f98795580"},{"name":"aws_organizations_config_rules_test.go","path":"test/landingzone/aws_organizations_config_rules_test.go","sha":"741f7204dff6e030f99decfc0fc1ab48257afa4f"},{"name":"aws_organizations_test.go","path":"test/landingzone/aws_organizations_test.go","sha":"b8b2a9d87d27b48adf3190d9254fe565e27e2834"},{"name":"guardduty_test.go","path":"test/landingzone/guardduty_test.go","sha":"417a1243767ad1098b1f497f9f4c47ca9f097b9c"},{"name":"kms_master_key_multiregion_test.go","path":"test/landingzone/kms_master_key_multiregion_test.go","sha":"9f401efbff5eec29f09ce4b4652c204f3e8e38cb"},{"name":"test_helpers.go","path":"test/landingzone/test_helpers.go","sha":"04d4a3e1246aa9ce5933ed947cfa96f73da38ed2"}]},{"name":"security","children":[{"name":"auto_update_test.go","path":"test/security/auto_update_test.go","sha":"c55fc7bde4cdd3ff7301d6b066133a3b00393677"},{"name":"cloudtrail_test.go","path":"test/security/cloudtrail_test.go","sha":"ba516c053d8a1ce2098e3762bb2fa98687d69298"},{"name":"cross_account_iam_roles_test.go","path":"test/security/cross_account_iam_roles_test.go","sha":"64ca042252283d2d5d26c39439c6eff0f5ac92ac"},{"name":"custom_iam_entity_test.go","path":"test/security/custom_iam_entity_test.go","sha":"514a06c2e5bab3c0537b67e9c75e33629248cfcd"},{"name":"fail2ban_test.go","path":"test/security/fail2ban_test.go","sha":"261978b73bec743d6bb3a74e1062366cff61ab5f"},{"name":"iam_groups_test.go","path":"test/security/iam_groups_test.go","sha":"7ee8649858a047022d4e508c2de7c5d6afc5046d"},{"name":"iam_ssm_test.go","path":"test/security/iam_ssm_test.go","sha":"20268ac744df04c901a1cbf81d042c1f535e5371"},{"name":"iam_user_password_policy_test.go","path":"test/security/iam_user_password_policy_test.go","sha":"e6eea3e767a427352fe9f0226e7fa3c39ed338d6"},{"name":"iam_users_test.go","path":"test/security/iam_users_test.go","sha":"e852d1d0b4f5e4e1a8ef503592b3ca4e291c6ad3"},{"name":"ip-lockdown-test-scripts","children":[{"name":"allow-several-users.sh","path":"test/security/ip-lockdown-test-scripts/allow-several-users.sh","sha":"2f75dbe0880ed0907b43db58b6ac030a0d0e9bd4"},{"name":"common.sh","path":"test/security/ip-lockdown-test-scripts/common.sh","sha":"cdfe11aca76607a4feaf254a394f32273b738c5c"},{"name":"index.html","path":"test/security/ip-lockdown-test-scripts/index.html","sha":"557db03de997c86a4a028e1ebd3a1ceb225be238"},{"name":"restrict-all-users.sh","path":"test/security/ip-lockdown-test-scripts/restrict-all-users.sh","sha":"a37c1ffc90f2532e7cc3f9f5a859b75c98661dc6"},{"name":"restrict-one-user.sh","path":"test/security/ip-lockdown-test-scripts/restrict-one-user.sh","sha":"4214e1c15102f4568d1e995aa82add46ee430237"},{"name":"sanity-check.sh","path":"test/security/ip-lockdown-test-scripts/sanity-check.sh","sha":"542ed72f4f0952ace67c9cbf2e5ac07e81e6870c"}]},{"name":"ip_lockdown_test.go","path":"test/security/ip_lockdown_test.go","sha":"14d5236b574215f568131ba7f915ba2812d92c55"},{"name":"kms_master_key_test.go","path":"test/security/kms_master_key_test.go","sha":"dee1e0e4db86084856b1045c1f30452c4d3d28be"},{"name":"ntp_test.go","path":"test/security/ntp_test.go","sha":"38c92a6ecc39a49629d6ff2f072e849da17ff2ec"},{"name":"os_hardening_test.go","path":"test/security/os_hardening_test.go","sha":"c50ac78e1b70a8b1cea2ac4b56de433795ef3a1e"},{"name":"saml_iam_roles_test.go","path":"test/security/saml_iam_roles_test.go","sha":"5623589ff477ec545bf6578d46795a49b42a6cb8"},{"name":"ssh_grunt_houston_test.go","path":"test/security/ssh_grunt_houston_test.go","sha":"d5f07e8ffc33add2341d2a6a4f39fbff1ad3d8c6"},{"name":"ssh_grunt_iam_test.go","path":"test/security/ssh_grunt_iam_test.go","sha":"a3117d391b095ba5bde04f1f3a817ffd839748c1"},{"name":"test_helpers.go","path":"test/security/test_helpers.go","sha":"fcd91c0059f4ab6701db6368fc2acda8b9d1dd60"},{"name":"test_helpers_aws_auth.go","path":"test/security/test_helpers_aws_auth.go","sha":"de42c70f5e1b875f994b433cf94f1ff6bacc7de7"},{"name":"tls_cert_private_test.go","path":"test/security/tls_cert_private_test.go","sha":"455501c058664b1066381be8c1423e68ba436fdf"}]}]}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"aws-cloud-trail-core-concepts\">AWS CloudTrail Core Concepts</h1><div class=\"preview__body--border\"></div><h2 class=\"preview__body--subtitle\" id=\"background\">Background</h2>\n<h3 class=\"preview__body--subtitle\" id=\"what-is-cloud-trail\">What is CloudTrail?</h3>\n<p>From the <a href=\"http://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html\" class=\"preview__body--description--blue\" target=\"_blank\">AWS documentation</a>:</p>\n<blockquote>\n<p>You can use AWS CloudTrail to get a history of AWS API calls and related events for your account. This includes calls\nmade by using the AWS Management Console, AWS SDKs, command line tools, and higher-level AWS services.</p>\n</blockquote>\n<h3 class=\"preview__body--subtitle\" id=\"why-use-cloud-trail\">Why use CloudTrail?</h3>\n<p>An important element of cloud security is auditing all AWS API calls. This can give you key insight into when a new port\nwas opened, when a new IAM User account was created, and other security-significant events. While it's trivially easy to\nturn on CloudTrail, thinking through where to store CloudTrail logs, how to guarantee CloudTrails logs aren't tampered\nwith, and getting alerts when certain API events occur is non-trivial.</p>\n<p>Note that <em>any</em> interaction with AWS ultimately results in an API call. This includes using the AWS Web Console, awscli,\nand any of the various AWS SDKs.</p>\n<h3 class=\"preview__body--subtitle\" id=\"what-is-a-cloud-trail-trail\">What is a CloudTrail Trail?</h3>\n<p>To setup CloudTrail, you enable an individual "Trail" which has certain configuration options. For example, a Trail could\nbe configured to collect logs from just a single AWS Region or all AWS Regions, it could optionally log to CloudWatch Logs,\noptionally use a KMS Key, etc.</p>\n<p>In practice, most teams will use a single CloudTrail Trail.</p>\n<h3 class=\"preview__body--subtitle\" id=\"whats-the-difference-between-cloud-trail-and-aws-config\">What's the difference between CloudTrail and AWS Config?</h3>\n<p>CloudTrail records every API call event in log files and provides convenient ways of viewing those logs. It treats the\n<em>API Call</em> as a first-class entity.</p>\n<p>AWS Config tracks changes to individual AWS resources and can alert you when a change is made that violates a defined\npolicy. It treats the <em>AWS Resource</em> as a first-class entity.</p>\n<p>Naturally, an API Call typically operates on a particular AWS Resource, so the AWS Web Console includes links to the\ncorresponding AWS Resource in AWS Config (and vice versa).</p>\n<h3 class=\"preview__body--subtitle\" id=\"cloud-trail-threat-model\">CloudTrail Threat Model</h3>\n<p>The following are the various parts of the cloudtrail module threat model:</p>\n<ul>\n<li>\n<p><strong>Deleting the S3 Bucket that stores CloudTrail events.</strong> An IAM User who has permissions to delete the S3 Bucket that\ncontains all CloudTrail events can delete all historical log data by deleting the S3 Bucket. Interestingly, CloudTrail\nwill still show the last 7 days of create, modify, and delete API calls in the AWS Web Console, even after the S3\nBucket is deleted.</p>\n<p>One way to protect against this is to set an alert if the S3 Bucket is deleted. In addition, an attacker could\ndelete the alert (!) so we also need an alert if any alerts are themselves deleted.</p>\n<p>To assist with access auditing, you can also enable S3 Access Logs so that any access or modification of the CloudTrail S3\nbucket will be logged to the separate S3 bucket. Of course, you'll need to ensure that the same user does not have access\nto the access logs bucket.</p>\n<p>Another option is to enable <a href=\"http://docs.aws.amazon.com/AmazonS3/latest/dev/crr.html\" class=\"preview__body--description--blue\" target=\"_blank\">S3 Cross-Region Replication</a> in\na cross-account scenario. That is, all S3 data is asynchronously replicated to another S3 Bucket in another AWS Account\nwhich you limit access to a very small number of trusted parties.</p>\n<p>Yet another option is to enable CloudWatch Logs integration so that CloudTrail events are published to a CloudWatch Logs\ngroup. The same deletion risk exists for an IAM user who has access to CloudWatch Logs. This is one reason among many\nwhy it is recommended to limit IAM access and prevent full administrator rights to any IAM user.</p>\n</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"resources-created\">Resources Created</h2>\n<p>This module creates the following AWS resources:</p>\n<ul>\n<li><strong>aws_s3_bucket:</strong> An S3 Bucket where all CloudTrail data is stored. You can configure for how long CloudTrail data\nis stored.</li>\n<li><strong>aws_kms_key:</strong> A KMS Customer Master Key (CMK) that encrypts all CloudTrail data. In order to view any read API log\nentries, or any API log entries older than 7 days, a user must have "decrypt" rights on this Key.</li>\n<li><strong>aws_cloudtrail:</strong> We create a CloudTrail "Trail" that records log data from all AWS Regions and also writes a hash\nof all log entries to S3 to allow for log file validation.</li>\n<li><strong>aws_cloudwatch_log_group:</strong> (optional) A CloudWatch Logs group where CloudTrail can publish events.</li>\n<li><strong>aws_iam_role:</strong> (optional) An IAM role for CloudTrail to use for publishing events to CloudWatch Logs.</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"operations\">Operations</h2>\n<h3 class=\"preview__body--subtitle\" id=\"where-are-cloud-trail-logs-stored\">Where are CloudTrail logs stored?</h3>\n<p>All CloudTrail log data is stored as discrete files in S3. This module configures those files to be encrypted with a KMS\nCustomer Master Key (CMK) used exclusively for CloudTrail.</p>\n<h3 class=\"preview__body--subtitle\" id=\"what-kind-of-data-do-cloud-trail-log-entries-contain\">What kind of data do CloudTrail log entries contain?</h3>\n<p>Here's an example CloudTrail entry:</p>\n<pre>{\n <span class=\"hljs-string\">\"eventVersion\"</span>: <span class=\"hljs-string\">\"1.04\"</span>,\n <span class=\"hljs-string\">\"userIdentity\"</span>: {\n <span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"IAMUser\"</span>,\n <span class=\"hljs-string\">\"principalId\"</span>: <span class=\"hljs-string\">\"AIDAIS2WCCNPT35B4US6W\"</span>,\n <span class=\"hljs-string\">\"arn\"</span>: <span class=\"hljs-string\">\"arn:aws:iam::123456789012:user/josh@phoenixdevops.com\"</span>,\n <span class=\"hljs-string\">\"accountId\"</span>: <span class=\"hljs-string\">\"087285199408\"</span>,\n <span class=\"hljs-string\">\"accessKeyId\"</span>: <span class=\"hljs-string\">\"AKIAJIMXOF147AFZDOXB\"</span>,\n <span class=\"hljs-string\">\"userName\"</span>: <span class=\"hljs-string\">\"josh@gruntwork.io\"</span>\n },\n <span class=\"hljs-string\">\"eventTime\"</span>: <span class=\"hljs-string\">\"2016-09-29T17:16:33Z\"</span>,\n <span class=\"hljs-string\">\"eventSource\"</span>: <span class=\"hljs-string\">\"kms.amazonaws.com\"</span>,\n <span class=\"hljs-string\">\"eventName\"</span>: <span class=\"hljs-string\">\"DescribeKey\"</span>,\n <span class=\"hljs-string\">\"awsRegion\"</span>: <span class=\"hljs-string\">\"us-west-2\"</span>,\n <span class=\"hljs-string\">\"sourceIPAddress\"</span>: <span class=\"hljs-string\">\"12.34.567.890\"</span>,\n <span class=\"hljs-string\">\"userAgent\"</span>: <span class=\"hljs-string\">\"terraform/0.7.4 aws-sdk-go/1.4.10 (go1.7.1; darwin; amd64)\"</span>,\n <span class=\"hljs-string\">\"requestParameters\"</span>: {\n <span class=\"hljs-string\">\"keyId\"</span>: <span class=\"hljs-string\">\"685be88d-5693-4c0e-ba64-2bab5d9806f3\"</span>\n },\n <span class=\"hljs-string\">\"responseElements\"</span>: <span class=\"hljs-literal\">null</span>,\n <span class=\"hljs-string\">\"requestID\"</span>: <span class=\"hljs-string\">\"785ead04-8668-11e6-8bd5-19543dc40616\"</span>,\n <span class=\"hljs-string\">\"eventID\"</span>: <span class=\"hljs-string\">\"6385bc87-a304-4358-9b65-50ece1898daa\"</span>,\n <span class=\"hljs-string\">\"readOnly\"</span>: <span class=\"hljs-literal\">true</span>,\n <span class=\"hljs-string\">\"resources\"</span>: [\n {\n <span class=\"hljs-string\">\"ARN\"</span>: <span class=\"hljs-string\">\"arn:aws:kms:us-west-2:087285199408:key/685be88d-5693-4c0e-ba64-2bab5d9806f3\"</span>,\n <span class=\"hljs-string\">\"accountId\"</span>: <span class=\"hljs-string\">\"087285199408\"</span>\n }\n ],\n <span class=\"hljs-string\">\"eventType\"</span>: <span class=\"hljs-string\">\"AwsApiCall\"</span>,\n <span class=\"hljs-string\">\"recipientAccountId\"</span>: <span class=\"hljs-string\">\"087285199408\"</span>\n },\n</pre>\n<p>As you can see, pretty much all relevant information is included in the call, including the identity of the requester,\nthe user agent, and the service being called.</p>\n<h3 class=\"preview__body--subtitle\" id=\"whats-the-best-way-to-view-cloud-trail-log-data\">What's the best way to view CloudTrail Log Data?</h3>\n<p>One way to view CloudTrail log data is just to download files directly from S3. That's how I obtained the example above.\nThe other way to view log data is directly in the AWS Web Console, which provides a convenient interface for viewing and\nfiltering all API activity for create, modify, and delete API calls for the last 7 days only.</p>\n<p>To view read API calls, or any data older than 7 days, you must access it directly in S3.</p>\n<p>Another approach is to view the logs in CloudWatch Logs. If the trail is configured to publish to a CloudWatch Logs group, each\nevent as described above is visible as a separate entry in the log group.</p>\n<p><em>Tip: IAM Users with IAM-granted access to CloudTrail can still view some data. See the <a href=\"#gotchas\" class=\"preview__body--description--blue\">Gotchas</a> for details.</em></p>\n<h3 class=\"preview__body--subtitle\" id=\"can-you-get-alerted-when-certain-api-events-occur\">Can you get alerted when certain API events occur?</h3>\n<p>Yes. It's possible to configure CloudTrail to also log events in <a href=\"http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html\" class=\"preview__body--description--blue\" target=\"_blank\">CloudWatch Logs</a>.\nYou can then configure CloudWatch Logs to emit a custom CloudWatch metric for certain events, and then create a CloudWatch\nalarm that notifies an SNS Topic when those events occur.</p>\n<p>This module does not currently support those features, but if you'd like us to add them please email info@gruntwork.io.</p>\n<h2 class=\"preview__body--subtitle\" id=\"gotchas\">Gotchas</h2>\n<ol>\n<li>\n<p>Even if an IAM User doesn't have access to the KMS Key used to encrypt all CloudTrail log data, if they have the\nappropriate IAM Policy, they can still view a subset of CloudTrail events in the AWS Web Console! Specifically, the\nAWS Web Console shows most API activity for create, modify, and delete API calls for the last 7 days only. Note that some activity is not visible, such as SSM calls. Viewing\nany other CloudTrail data does require access to the KMS Key.</p>\n</li>\n<li>\n<p>CloudTrail logs are not delivered instantly to the S3 Bucket. There's typically a delay of a few minutes. While AWS\ndocumentation states that it takes 15 minutes, in practice we've found it to be around 5 minutes in most cases.</p>\n</li>\n<li>\n<p>CloudTrail records not only API calls made by human IAM Users, but also API calls made by IAM Roles, and even API calls\nmade on behalf of an IAM User by internal AWS Services. You can identify this last type of API call by looking for an\n<code>invokedBy</code> property in the CloudTrail event. For example:</p>\n<pre><span class=\"hljs-string\">\"invokedBy\"</span>:<span class=\"hljs-string\">\"signin.amazonaws.com\"</span>\n</pre>\n</li>\n<li>\n<p>If you provide an existing S3 bucket rather than allow this module to create one, you'll need to apply the <a href=\"https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-s3-bucket-policy-for-cloudtrail.html\" class=\"preview__body--description--blue\" target=\"_blank\">recommended\nS3 Bucket Policy</a>.\nFurthermore, if you provide an existing S3 bucket, the module will not enable access logging even if you use\n<code>enable_s3_server_access_logging=true</code>. The access logging bucket will be created, but you'll need to manually enable logging\nin the bucket properties of the existing bucket.</p>\n</li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"known-issues\">Known Issues</h2>\n<ul>\n<li>\n<p>Terraform has a bug where you will see a diff on the S3 lifecycle rules on every <code>terraform apply</code> or <code>terraform plan</code>. See\n<a href=\"https://github.com/hashicorp/terraform/issues/9119\" class=\"preview__body--description--blue\" target=\"_blank\">#9119</a> to track progress on this issue.</p>\n</li>\n<li>\n<p>If you attempt to enable or disable archiving of log files, Terraform will attempt to delete and re-create your existing S3\nBucket. This will fail because your Bucket won't be empty, but more importantly, the goal here is just to change some S3\nLifecycle Rules, so a destroy/re-create is unnecessary.</p>\n<p>Here's what the <code>terraform plan</code> output looks like if you attempt to disable archiving:</p>\n<pre>- module<span class=\"hljs-selector-class\">.cloudtrail</span><span class=\"hljs-selector-class\">.aws_s3_bucket</span><span class=\"hljs-selector-class\">.cloudtrail_with_logs_archived</span>\n\n+ module<span class=\"hljs-selector-class\">.cloudtrail</span><span class=\"hljs-selector-class\">.aws_s3_bucket</span><span class=\"hljs-selector-class\">.cloudtrail_with_logs_not_archived</span>\n acceleration_status: <span class=\"hljs-string\">\"<computed>\"</span>\n acl: <span class=\"hljs-string\">\"private\"</span>\n arn: <span class=\"hljs-string\">\"<computed>\"</span>\n ...\n</pre>\n<p>Fortunately, there's a 1-line workaround using Terraform's built-in state management features:</p>\n<p><strong>If you are ENABLING archiving:</strong> <code>terraform state mv module.cloudtrail.aws_s3_bucket.cloudtrail_with_logs_archived module.cloudtrail.aws_s3_bucket.cloudtrail_with_logs_not_archived</code></p>\n<p><strong>If you are DISABLING archiving:</strong> <code>terraform state mv module.cloudtrail.aws_s3_bucket.cloudtrail_with_logs_not_archived module.cloudtrail.aws_s3_bucket.cloudtrail_with_logs_archived</code></p>\n<p>These commands tell Terraform to update the state file, and treat the bucket that Terraform wanted to create as already\nexisting. Now you'll get a yellow "modify" output when running <code>terraform plan</code> and no destroy/re-create will be needed.</p>\n</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"todo\">TODO</h2>\n<ul>\n<li>\n<p>Document <a href=\"http://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-cli.html\" class=\"preview__body--description--blue\" target=\"_blank\">CLI-based validation</a>\nof a CloudTrail log file to ensure it hasn't been tampered with.</p>\n</li>\n<li>\n<p>Consider enabling <a href=\"http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html\" class=\"preview__body--description--blue\" target=\"_blank\">MFA Delete</a> on the S3 Bucket\nthat stores the CloudTrail events.</p>\n</li>\n<li>\n<p>Implement support for CloudWatch Logs and declaring specific alerts on individual API events.</p>\n<ul>\n<li>Examples:\n<ul>\n<li>Alert if CloudTrail Logging is paused.</li>\n<li>Alert if CloudTrail S3 Bucket is deleted.</li>\n<li>Alert if any IAM Policy, IAM User, or IAM Role is changed (or would this be too noisy?)</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n","repoName":"module-security","repoRef":"v0.28.7","serviceDescriptor":{"serviceName":"AWS CloudTrail","serviceRepoName":"module-security","serviceRepoOrg":"gruntwork-io","serviceMainReadmePath":"/modules/cloudtrail","cloudProviders":["aws"],"description":"Run AWS CloudTrail to maintain an audit log of all API calls in your AWS account and write the logs to an S3 bucket, encrypted with KMS.","imageUrl":"cloudtrail.png","licenseType":"subscriber","technologies":["Terraform"],"compliance":[],"tags":[""]},"serviceCategoryName":"Landing Zone","fileName":"core-concepts.md","filePath":"/modules/cloudtrail/core-concepts.md","title":"Repo Browser: AWS CloudTrail","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}