Skip to content

Commit

Permalink
Monitor AMIs, Service Limits, PHD events (#2)
Browse files Browse the repository at this point in the history
* only alert on backup failures
* update to support monitoring for unavailable/deleted amis that might still be in use
* monitor for account lifecycle events
* switch to trivy and fix checks
* refine iam access analyzer support
* add service limit checks
  • Loading branch information
cdaniluk authored Aug 9, 2024
1 parent f90fc28 commit 581fff7
Show file tree
Hide file tree
Showing 32 changed files with 2,181 additions and 156 deletions.
26 changes: 0 additions & 26 deletions .github/workflows/tfsec.yaml

This file was deleted.

31 changes: 31 additions & 0 deletions .github/workflows/trivy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: trivy
on:
push:
branches:
- master

jobs:
trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install prerequisites
run: ./bin/install-ubuntu.sh
- name: Terraform init
run: terraform init --backend=false
- name: Trivy scan
uses: aquasecurity/trivy-action@master
with:
scan-type: 'config'
hide-progress: false
format: 'sarif'
output: 'trivy-results.sarif'
exit-code: '1'
ignore-unfixed: true
severity: 'CRITICAL,HIGH'

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ tmp

# modules should not submit lock files
.terraform.lock.hcl

lambda/*.zip

**/__pycache__
3 changes: 0 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ repos:
- id: terraform_validate
args:
- --hook-config=--retry-once-with-cleanup=true
exclude: examples\/
- id: terraform_tflint
alias: terraform_tflint_nocreds
name: terraform_tflint_nocreds
- id: terraform_trivy
args:
- --args=--skip-dirs="**/.terraform,examples/*"
- id: terraform_providers_lock
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
Expand Down
2 changes: 1 addition & 1 deletion .tflint.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ config {

plugin "aws" {
enabled = true
version = "0.12.0"
version = "0.30.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}

Expand Down
68 changes: 57 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
# terraform-aws-rhythmic-account-monitor
Configures AWS health and account related notifications

[![tflint](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/workflows/tflint/badge.svg?branch=master&event=push)](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions?query=workflow%3Atflint+event%3Apush+branch%3Amaster)
[![tfsec](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/workflows/tfsec/badge.svg?branch=master&event=push)](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions?query=workflow%3Atfsec+event%3Apush+branch%3Amaster)
[![yamllint](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/workflows/yamllint/badge.svg?branch=master&event=push)](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions?query=workflow%3Ayamllint+event%3Apush+branch%3Amaster)
[![misspell](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/workflows/misspell/badge.svg?branch=master&event=push)](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions?query=workflow%3Amisspell+event%3Apush+branch%3Amaster)
[![pre-commit-check](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/workflows/pre-commit-check/badge.svg?branch=master&event=push)](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions?query=workflow%3Apre-commit-check+event%3Apush+branch%3Amaster)
This module is used to monitor AWS accounts and send notifications for various events including:
- AWS Backup and Vault Lock lifecycle changes
- AWS Organizations account lifecycle changes
- AWS PHD events
- IAM access analyzer unused permissions/resources findings
- Resources using missing AMIs
- Service Quota limits

[![tflint](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions/workflows/tflint.yaml/badge.svg)](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions/workflows/tflint.yaml)
[![trivy](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions/workflows/trivy.yaml/badge.svg)](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions/workflows/trivy.yaml)
[![yamllint](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions/workflows/yamllint.yaml/badge.svg)](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions/workflows/yamllint.yaml)
[![misspell](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions/workflows/tflint.yaml/badge.svg)](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions/workflows/tflint.yaml)
[![pre-commit-check](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions/workflows/pre-commit.yaml/badge.svg)](https://github.com/rhythmictech/terraform-aws-rhythmic-account-monitor/actions/workflows/pre-commit.yaml)
<a href="https://twitter.com/intent/follow?screen_name=RhythmicTech"><img src="https://img.shields.io/twitter/follow/RhythmicTech?style=social&logo=twitter" alt="follow on Twitter"></a>

## Example
Expand All @@ -28,13 +36,15 @@ We open source the vast majority of the resources we use to deliver our managed
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.62 |
| <a name="requirement_archive"></a> [archive](#requirement\_archive) | >= 2.5.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.40 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.36.0 |
| <a name="provider_archive"></a> [archive](#provider\_archive) | 2.5.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.62.0 |

## Modules

Expand All @@ -46,22 +56,51 @@ We open source the vast majority of the resources we use to deliver our managed

| Name | Type |
|------|------|
| [aws_accessanalyzer_analyzer.analyzer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/accessanalyzer_analyzer) | resource |
| [aws_accessanalyzer_analyzer.analyzer_unused](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/accessanalyzer_analyzer) | resource |
| [aws_cloudwatch_event_rule.analyzer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_accessanalyzer_analyzer.unused_access_analyzer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/accessanalyzer_analyzer) | resource |
| [aws_accessanalyzer_archive_rule.archive_rules](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/accessanalyzer_archive_rule) | resource |
| [aws_cloudwatch_event_rule.backup](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_rule.backup_event](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_rule.backup_vaultlock](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_rule.control_tower](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_rule.glacier_vaultlock](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_target.analyzer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_cloudwatch_event_rule.health](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_rule.monitor_ami_usage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_rule.monitor_service_quotas](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_rule.organizations](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_target.backup](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_cloudwatch_event_target.backup_event](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_cloudwatch_event_target.backup_vaultlock](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_cloudwatch_event_target.control_tower](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_cloudwatch_event_target.glacier_vaultlock](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_cloudwatch_event_target.health](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_cloudwatch_event_target.monitor_ami_usage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_cloudwatch_event_target.monitor_service_quotas](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_cloudwatch_event_target.organizations](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_cloudwatch_log_group.monitor_ami_usage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_cloudwatch_log_group.monitor_service_quotas](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_iam_policy.monitor_ami_usage_execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_policy.monitor_service_quotas_execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.monitor_ami_usage_execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role.monitor_service_quotas_execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.monitor_ami_usage_execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.monitor_service_quotas_execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.monitor_service_quotas_security_analyst](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_lambda_function.monitor_ami_usage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |
| [aws_lambda_function.monitor_service_quotas](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |
| [aws_lambda_permission.monitor_ami_usage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |
| [aws_lambda_permission.monitor_service_quotas](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |
| [aws_sns_topic.account_alerts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource |
| [aws_sns_topic_policy.account_alerts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_policy) | resource |
| [aws_sns_topic_subscription.account_alerts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
| [archive_file.monitor_ami_usage](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
| [archive_file.monitor_service_quotas](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.account_alerts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.lambda_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.monitor_ami_usage_execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.monitor_service_quotas_execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_kms_alias.notifications](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
| [aws_secretsmanager_secret.datadog_api_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/secretsmanager_secret) | data source |
| [aws_secretsmanager_secret_version.datadog_api_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/secretsmanager_secret_version) | data source |

Expand All @@ -71,7 +110,14 @@ We open source the vast majority of the resources we use to deliver our managed
|------|-------------|------|---------|:--------:|
| <a name="input_datadog_api_key_secret_arn"></a> [datadog\_api\_key\_secret\_arn](#input\_datadog\_api\_key\_secret\_arn) | ARN of the AWS Secret containing the Datadog API key | `string` | n/a | yes |
| <a name="input_enable_iam_access_analyzer"></a> [enable\_iam\_access\_analyzer](#input\_enable\_iam\_access\_analyzer) | A boolean flag to enable/disable IAM Access Analyzer | `bool` | `false` | no |
| <a name="input_enable_iam_access_analyzer_organization"></a> [enable\_iam\_access\_analyzer\_organization](#input\_enable\_iam\_access\_analyzer\_organization) | A boolean flag to enable/disable IAM Access Analyzer at the organization level (requires enable\_iam\_access\_analyzer to be true and IAM Access Analyzer to be enabled at the organization level) | `bool` | `false` | no |
| <a name="input_iam_access_analyzer_unused_archive_rules"></a> [iam\_access\_analyzer\_unused\_archive\_rules](#input\_iam\_access\_analyzer\_unused\_archive\_rules) | List of IAM resources to auto-archive unused access findings for | <pre>list(object({<br> accounts = optional(list(string))<br> finding_type = string<br> is_partial = bool<br> resources = optional(list(string))<br> resource_type = optional(string)<br> }))</pre> | `[]` | no |
| <a name="input_iam_analyzer_unused_access_age"></a> [iam\_analyzer\_unused\_access\_age](#input\_iam\_analyzer\_unused\_access\_age) | The age in days after which IAM access is considered unused. | `number` | `90` | no |
| <a name="input_name_prefix"></a> [name\_prefix](#input\_name\_prefix) | Prefix for all resource names | `string` | `"rhythmic-"` | no |
| <a name="input_notify_ec2_missing_ami"></a> [notify\_ec2\_missing\_ami](#input\_notify\_ec2\_missing\_ami) | Whether to notify when EC2 instances are using missing AMIs | `bool` | `false` | no |
| <a name="input_notify_ec2_missing_ami_if_snapshot_exists"></a> [notify\_ec2\_missing\_ami\_if\_snapshot\_exists](#input\_notify\_ec2\_missing\_ami\_if\_snapshot\_exists) | Whether to notify when EC2 instances are using missing AMIs but snapshots exist | `bool` | `true` | no |
| <a name="input_service_quota_region_list"></a> [service\_quota\_region\_list](#input\_service\_quota\_region\_list) | List of regions to monitor for service quotas. Note that you cannot monitor across partitions (e.g. us-east-1 and us-gov-east-1) | `list(string)` | <pre>[<br> "us-east-1"<br>]</pre> | no |
| <a name="input_service_quota_threshold"></a> [service\_quota\_threshold](#input\_service\_quota\_threshold) | The threshold percentage for service quota alerts | `number` | `80` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | User-Defined tags | `map(string)` | `{}` | no |

## Outputs
Expand Down
18 changes: 9 additions & 9 deletions backup.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
resource "aws_cloudwatch_event_rule" "backup" {

name = "backup-events-monitor"
name = "${var.name_prefix}backup-events-monitor"
description = "Capture AWS Backup events"

event_pattern = jsonencode({
source = ["aws.backup"]
detail-type = ["AWS API Call via CloudTrail"]
source = ["aws.backup"]
detail = {
eventSource = ["backup.amazonaws.com"]
eventName = [
"DeleteBackupPlan",
"DeleteBackupSelection",
Expand All @@ -23,20 +21,22 @@ resource "aws_cloudwatch_event_rule" "backup" {
resource "aws_cloudwatch_event_target" "backup" {
arn = aws_sns_topic.account_alerts.arn
rule = aws_cloudwatch_event_rule.backup.name
target_id = "SendToSNS"
target_id = "SendToSNS-backup-config-changes"
}

# TODO only include negative backup events for now until the datadog terraform
# provider adds support for event pipelines
resource "aws_cloudwatch_event_rule" "backup_event" {

name_prefix = "backup-events-monitor"
description = "AWS Backup failures"
name_prefix = "${var.name_prefix}backup-events-monitor"
description = "Capture AWS Backup failures"

event_pattern = <<EOT
{
"source": ["aws.backup"],
"detail-type": ["Backup Job State Change"],
"detail": {
"state": ["COMPLETED", "FAILED", "ABORTED"]
"state": ["EXPIRED", "FAILED", "ABORTED"]
}
}
EOT
Expand All @@ -45,5 +45,5 @@ EOT
resource "aws_cloudwatch_event_target" "backup_event" {
arn = aws_sns_topic.account_alerts.arn
rule = aws_cloudwatch_event_rule.backup_event.name
target_id = "SendToSNS"
target_id = "SendToSNS-backup-events"
}
3 changes: 3 additions & 0 deletions bin/install-ubuntu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ pre-commit init-templatedir ~/.git-template

echo 'installing terraform with tfenv'
tfenv install

wget https://github.com/aquasecurity/trivy/releases/download/v0.49.1/trivy_0.49.1_Linux-64bit.deb
sudo dpkg -i trivy_0.49.1_Linux-64bit.deb
56 changes: 0 additions & 56 deletions examples/basic/README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,2 @@
# basic example
A basic example for this repository

## Code
Look to [main.tf](./main.tf), or be helpful and copy/paste that code here.

## Applying
```
> terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
example = {
"tags_module" = {
"name" = "TEST"
"name32" = "TEST"
"name6" = "TEST"
"namenosymbols" = "TEST"
"tags" = {
"Name" = "TEST"
"terraform_managed" = true
"terraform_module" = "terraform-terraform-tags-1.0.0"
"terraform_root_module" = "."
"terraform_workspace" = "default"
}
"tags_as_list_of_maps" = [
{
"key" = "Name"
"value" = "TEST"
},
{
"key" = "terraform_managed"
"value" = true
},
{
"key" = "terraform_module"
"value" = "terraform-terraform-tags-1.0.0"
},
{
"key" = "terraform_root_module"
"value" = "."
},
{
"key" = "terraform_workspace"
"value" = "default"
},
]
"tags_no_name" = {
"terraform_managed" = true
"terraform_module" = "terraform-terraform-tags-1.0.0"
"terraform_root_module" = "."
"terraform_workspace" = "default"
}
}
}
```
Loading

0 comments on commit 581fff7

Please sign in to comment.