diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..b50cee9 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,20 @@ +name: check +on: [push, pull_request] + +jobs: + build: + runs-on: macOS-latest + steps: + - uses: actions/checkout@v1 + + - name: Install prereq + run: | + brew install docker tfenv tflint + tfenv install + + - name: tf fmt + run: | + terraform fmt + - name: tflint + run: | + tflint diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..8e688d7 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +--- +repos: +- repo: git://github.com/antonbabenko/pre-commit-terraform + rev: v1.19.0 + hooks: + - id: terraform_fmt + - id: terraform_docs +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: end-of-file-fixer + - id: trailing-whitespace + - id: no-commit-to-branch diff --git a/.terraform-version b/.terraform-version new file mode 100644 index 0000000..32ffda3 --- /dev/null +++ b/.terraform-version @@ -0,0 +1 @@ +0.12.13 diff --git a/README.md b/README.md new file mode 100644 index 0000000..0eca0fa --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# terraform-aws-inspector + + +[![](https://github.com/rhythmictech/terraform-aws-inspector/workflows/check/badge.svg)](https://github.com/rhythmictech/terraform-aws-inspector/actions) + +Configures AWS Inspector. Optionally configures a CloudWatch scheduled event to trigger assessments based on a specified schedule. + +``` +module "inspector" { + source = "git::ssh://git@github.com/rhythmictech/terraform-aws-inspector" + match_tags = { + "AWSInspector": "enabled" + } +} +``` + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|:----:|:-----:|:-----:| +| inspector\_cron\_schedule | Cron schedule to use \(see https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html for formatting\) | string | `"cron(0 20 23 * ? *)"` | no | +| match\_tags | Map of tags and corresponding values to match against for AWS Inspector | map(string) | n/a | yes | +| name | Name of the assessment template/targets | string | `"Inspector"` | no | +| schedule\_inspector | Indicate whether a cloudwatch rule should be created to trigger inspector automatically | bool | `"true"` | no | +| tags | Tags to apply to resources that support tagging | map(string) | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| inspector\_assessment\_target\_arn | | +| inspector\_assessment\_template\_arn | | + + diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..1052072 --- /dev/null +++ b/main.tf @@ -0,0 +1,74 @@ +resource "aws_inspector_resource_group" "resource_group" { + tags = var.match_tags +} + +resource "aws_inspector_assessment_target" "target" { + name = var.name + resource_group_arn = aws_inspector_resource_group.resource_group.arn +} + +resource "aws_inspector_assessment_template" "template" { + name = var.name + target_arn = aws_inspector_assessment_target.target.arn + duration = 3600 + + # TODO don't hardcode this + rules_package_arns = [ + "arn:aws:inspector:us-east-1:316112463485:rulespackage/0-gEjTy7T7", + "arn:aws:inspector:us-east-1:316112463485:rulespackage/0-rExsr2X8", + "arn:aws:inspector:us-east-1:316112463485:rulespackage/0-R01qwB5Q", + "arn:aws:inspector:us-east-1:316112463485:rulespackage/0-gBONHN9h", + ] +} + +resource "aws_cloudwatch_event_rule" "inspector_trigger" { + count = var.schedule_inspector ? 1 : 0 + name = "${var.name}-Scheduler" + description = "Schedules AWS Inspector runs" + schedule_expression = var.inspector_cron_schedule + tags = var.tags +} + +data "aws_iam_policy_document" "cw_inspector_assume_role" { + statement { + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["events.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "cw_inspector_iam_role" { + count = var.schedule_inspector ? 1 : 0 + assume_role_policy = data.aws_iam_policy_document.cw_inspector_assume_role.json + name_prefix = "${var.name}-cw-role-" + tags = var.tags + + lifecycle { + create_before_destroy = true + } +} + +data "aws_iam_policy_document" "cw_inspector_policy_doc" { + statement { + actions = ["inspector:StartAssessmentRun"] + resources = ["*"] + } +} + +resource "aws_iam_role_policy" "cw_inspector_policy" { + count = var.schedule_inspector ? 1 : 0 + name_prefix = "${var.name}-cwinspector-" + role = aws_iam_role.cw_inspector_iam_role[0].id + policy = data.aws_iam_policy_document.cw_inspector_policy_doc.json +} + +resource "aws_cloudwatch_event_target" "inspector_target" { + count = var.schedule_inspector ? 1 : 0 + arn = aws_inspector_assessment_template.template.arn + role_arn = aws_iam_role.cw_inspector_iam_role[0].arn + rule = aws_cloudwatch_event_rule.inspector_trigger[0].name + target_id = "${var.name}-Scheduler" +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..5f85f1a --- /dev/null +++ b/outputs.tf @@ -0,0 +1,7 @@ +output "inspector_assessment_target_arn" { + value = aws_inspector_assessment_target.target.arn +} + +output "inspector_assessment_template_arn" { + value = aws_inspector_assessment_template.template.arn +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..f51849a --- /dev/null +++ b/variables.tf @@ -0,0 +1,28 @@ +variable "name" { + default = "Inspector" + description = "Name of the assessment template/targets" + type = string +} + +variable "match_tags" { + description = "Map of tags and corresponding values to match against for AWS Inspector" + type = map(string) +} + +variable "schedule_inspector" { + default = true + description = "Indicate whether a cloudwatch rule should be created to trigger inspector automatically" + type = bool +} + +variable "inspector_cron_schedule" { + default = "cron(0 20 23 * ? *)" + description = "Cron schedule to use (see https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html for formatting)" + type = string +} + +variable "tags" { + default = {} + description = "Tags to apply to resources that support tagging" + type = map(string) +}