From 503c53255d2618928131f05a341f847bd97b204f Mon Sep 17 00:00:00 2001 From: jsclarridge <2491291+jsclarridge@users.noreply.github.com> Date: Fri, 1 Nov 2019 09:07:10 -0700 Subject: [PATCH] Upgrade to tf 12 syntax; add terratest plumbing https://www.pivotaltracker.com/story/show/169407344 --- .dependabot/config.yml | 12 +++ .gitignore | 5 + .golangci.yml | 6 ++ .pre-commit-config.yaml | 14 ++- .terraform-version | 1 - Makefile | 17 +++ README.md | 37 +++++-- examples/simple/main.tf | 5 + examples/simple/variables.tf | 7 ++ go.mod | 5 + go.sum | 183 ++++++++++++++++++++++++++++++++ main.tf | 164 ++++++++++++++++++++++------ outputs.tf | 9 +- test/terraform_aws_logs_test.go | 35 ++++++ variables.tf | 49 ++++----- versions.tf | 4 + 16 files changed, 481 insertions(+), 72 deletions(-) create mode 100644 .dependabot/config.yml create mode 100644 .gitignore create mode 100644 .golangci.yml delete mode 100644 .terraform-version create mode 100644 Makefile create mode 100644 examples/simple/main.tf create mode 100644 examples/simple/variables.tf create mode 100644 go.mod create mode 100644 go.sum create mode 100644 test/terraform_aws_logs_test.go create mode 100644 versions.tf diff --git a/.dependabot/config.yml b/.dependabot/config.yml new file mode 100644 index 0000000..c347349 --- /dev/null +++ b/.dependabot/config.yml @@ -0,0 +1,12 @@ +version: 1 +update_configs: + # Keep go modules up to date, batching pull requests weekly + - package_manager: "go:modules" + directory: "/" + update_schedule: "weekly" + # Apply default reviewer @trussworks/waddlers group to PRs + default_reviewers: + - "trussworks/waddlers" + # Apply dependencies label to PRs + default_labels: + - "dependencies" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c871834 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +.terraform +terraform.tfstate +terraform.tfstate.backup +terraform.tfstate.*.backup diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..e193496 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,6 @@ +linters: + enable: + - gosec + - golint + - gofmt + - goimports diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8d31e32..565b87f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: git://github.com/pre-commit/pre-commit-hooks - rev: v2.2.3 + rev: v2.4.0 hooks: - id: check-json - id: check-merge-conflict @@ -12,13 +12,19 @@ repos: - id: trailing-whitespace - repo: git://github.com/igorshubovych/markdownlint-cli - rev: v0.17.0 + rev: v0.19.0 hooks: - id: markdownlint - repo: git://github.com/antonbabenko/pre-commit-terraform - rev: v1.12.0 + rev: v1.19.0 hooks: - id: terraform_docs - id: terraform_fmt - - id: terraform_validate_no_variables + + - repo: git://github.com/golangci/golangci-lint + rev: v1.21.0 + hooks: + - id: golangci-lint + entry: golangci-lint run --verbose + verbose: true diff --git a/.terraform-version b/.terraform-version deleted file mode 100644 index a95c45d..0000000 --- a/.terraform-version +++ /dev/null @@ -1 +0,0 @@ -0.11.14 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9bf3468 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +.PHONY: ensure_pre_commit +ensure_pre_commit: .git/hooks/pre-commit ## Ensure pre-commit is installed +.git/hooks/pre-commit: /usr/local/bin/pre-commit + pre-commit install + pre-commit install-hooks + +.PHONY: pre_commit_tests +pre_commit_tests: ensure_pre_commit ## Run pre-commit tests + pre-commit run --all-files + +.PHONY: test +test: pre_commit_tests + go test -count 1 -v -timeout 90m ./test/... + +.PHONY: clean +clean: + rm -f .*.stamp diff --git a/README.md b/README.md index 5ef9163..a5f9aa3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - Supports two main uses cases: 1. Creates and configures a single private S3 bucket for storing logs from various AWS services, which are nested as bucket prefixes. Logs will expire after a default of 90 days, with option to configure retention value. @@ -81,11 +80,18 @@ Logging from the following services is supported for both cases: ]) } +## Terraform Versions + +Terraform 0.12. Pin module version to ~> 4.x Submit pull-requests to master branch. + +Terraform 0.11. Pin module version to ~> 3.5.0. Submit pull-requests to terraform011 branch. + + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| alb\_logs\_prefixes | S3 key prefixes for ALB logs. | list | `[ "alb" ]` | no | +| alb\_logs\_prefixes | S3 key prefixes for ALB logs. | list(string) | `[ "alb" ]` | no | | allow\_alb | Allow ALB service to log to bucket. | string | `"false"` | no | | allow\_cloudtrail | Allow Cloudtrail service to log to bucket. | string | `"false"` | no | | allow\_cloudwatch | Allow Cloudwatch service to export logs to bucket. | string | `"false"` | no | @@ -93,16 +99,16 @@ Logging from the following services is supported for both cases: | allow\_elb | Allow ELB service to log to bucket. | string | `"false"` | no | | allow\_nlb | Allow NLB service to log to bucket. | string | `"false"` | no | | allow\_redshift | Allow Redshift service to log to bucket. | string | `"false"` | no | -| cloudtrail\_accounts | List of accounts for CloudTrail logs. By default limits to the current account. | list | `[]` | no | +| cloudtrail\_accounts | List of accounts for CloudTrail logs. By default limits to the current account. | list(string) | `[]` | no | | cloudtrail\_logs\_prefix | S3 prefix for CloudTrail logs. | string | `"cloudtrail"` | no | | cloudwatch\_logs\_prefix | S3 prefix for CloudWatch log exports. | string | `"cloudwatch"` | no | -| config\_accounts | List of accounts for Config logs. By default limits to the current account. | list | `[]` | no | +| config\_accounts | List of accounts for Config logs. By default limits to the current account. | list(string) | `[]` | no | | config\_logs\_prefix | S3 prefix for AWS Config logs. | string | `"config"` | no | | create\_public\_access\_block | Whether to create a public_access_block restricting public access to the bucket. | string | `"true"` | no | | default\_allow | Whether all services included in this module should be allowed to write to the bucket by default. Alternatively select individual services. It's recommended to use the default bucket ACL of log-delivery-write. | string | `"true"` | no | -| elb\_accounts | List of accounts for ELB logs. By default limits to the current account. | list | `[]` | no | +| elb\_accounts | List of accounts for ELB logs. By default limits to the current account. | list(string) | `[]` | no | | elb\_logs\_prefix | S3 prefix for ELB logs. | string | `"elb"` | no | -| nlb\_accounts | List of accounts for NLB logs. By default limits to the current account. | list | `[]` | no | +| nlb\_accounts | List of accounts for NLB logs. By default limits to the current account. | list(string) | `[]` | no | | nlb\_logs\_prefix | S3 prefix for NLB logs. | string | `"nlb"` | no | | redshift\_logs\_prefix | S3 prefix for RedShift logs. | string | `"redshift"` | no | | region | Region where the AWS S3 bucket will be created. | string | n/a | yes | @@ -150,3 +156,22 @@ As for policy creation, all policies are now turned on or off via the `allow_*` the `effect` block in the bucket policy for that resource will be modified to `Allow` whereas by default it will be set to `Deny`. Previously this module used a template to add or remove JSON text from the policy before rendering. The new module explicitly adds all resource policies as `Deny` and leaves it up to you to enable them. + +## Developer Setup + +Install dependencies (macOS) + + brew install pre-commit go terraform terraform-docs + +### Testing + +[Terratest](https://github.com/gruntwork-io/terratest) is being used for +automated testing with this module. Tests in the `test` folder can be run +locally by running the following command: + + make test + +Or with aws-vault: + + AWS_VAULT_KEYCHAIN_NAME=YOUR-KEYCHAIN-NAME aws-vault exec YOUR-AWS-PROFILE -- make test + diff --git a/examples/simple/main.tf b/examples/simple/main.tf new file mode 100644 index 0000000..59cd580 --- /dev/null +++ b/examples/simple/main.tf @@ -0,0 +1,5 @@ +module "aws_logs" { + source = "../../" + s3_bucket_name = var.logs_bucket + region = var.region +} diff --git a/examples/simple/variables.tf b/examples/simple/variables.tf new file mode 100644 index 0000000..3f4b117 --- /dev/null +++ b/examples/simple/variables.tf @@ -0,0 +1,7 @@ +variable "logs_bucket" { + type = string +} + +variable "region" { + type = string +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..8e1e173 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/trussworks/terraform-aws-logs + +go 1.13 + +require github.com/gruntwork-io/terratest v0.22.2 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f5d8021 --- /dev/null +++ b/go.sum @@ -0,0 +1,183 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +github.com/Azure/azure-sdk-for-go v32.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.1/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/azure/auth v0.3.0/go.mod h1:CI4BQYBct8NS7BXNBBX+RchsFsUu5+oz+OSyR/ZIi7U= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.0/go.mod h1:rNYMNAefZMRowqCV0cVhr/YDW5dD7afFq9nXAXL4ykE= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/aws/aws-sdk-go v1.23.8 h1:G/azJoBN0pnhB3B+0eeC4yyVFYIIad6bbzg6wwtImqk= +github.com/aws/aws-sdk-go v1.23.8/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= +github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c h1:jWtZjFEUE/Bz0IeIhqCnyZ3HG6KRXSntXe4SjtuTH7c= +github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gruntwork-io/gruntwork-cli v0.5.1/go.mod h1:IBX21bESC1/LGoV7jhXKUnTQTZgQ6dYRsoj/VqxUSZQ= +github.com/gruntwork-io/terratest v0.22.2 h1:rIuiDbe5Ur+EYePWtqtzsdXojUfJECXdD92hQRKY5sk= +github.com/gruntwork-io/terratest v0.22.2/go.mod h1:veL2PxiS2Z5S63ERnyiIY/sxgmXJpZD8YZybiqvduwQ= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= +github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.9.1-0.20190821000710-329ecc3c9c34/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.0.0-20181110191121-a33c8200050f/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/apimachinery v0.0.0-20190704094520-6f131bee5e2c/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/client-go v0.0.0-20190704095228-386e588352a4/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= diff --git a/main.tf b/main.tf index e5fc6c4..9b47f9e 100644 --- a/main.tf +++ b/main.tf @@ -84,17 +84,21 @@ # Get the account id of the AWS ELB service account in a given region for the # purpose of whitelisting in a S3 bucket policy. -data "aws_elb_service_account" "main" {} +data "aws_elb_service_account" "main" { +} # Get the account id of the RedShift service account in a given region for the # purpose of allowing RedShift to store audit data in S3. -data "aws_redshift_service_account" "main" {} +data "aws_redshift_service_account" "main" { +} # The AWS region currently being used. -data "aws_region" "current" {} +data "aws_region" "current" { +} # The AWS account id -data "aws_caller_identity" "current" {} +data "aws_caller_identity" "current" { +} # # S3 Bucket @@ -237,33 +241,126 @@ data "template_file" "bucket_policy" { } JSON + vars = { - region = "${var.region}" - bucket_arn = "${format("arn:aws:s3:::%s", var.s3_bucket_name)}" - alb_principal = "${data.aws_elb_service_account.main.arn}" - alb_effect = "${(var.default_allow || var.allow_alb) ? "Allow" : "Deny"}" - alb_resources = "${jsonencode(formatlist(format("arn:aws:s3:::%s/%%s/*", var.s3_bucket_name), var.alb_logs_prefixes))}" - cloudwatch_effect = "${(var.default_allow || var.allow_cloudwatch) ? "Allow" : "Deny"}" - cloudwatch_resources = "${jsonencode(format("arn:aws:s3:::%s/%s/*", var.s3_bucket_name, var.cloudwatch_logs_prefix))}" - cloudtrail_effect = "${(var.default_allow || var.allow_cloudtrail) ? "Allow" : "Deny"}" - cloudtrail_resources = "${length(var.cloudtrail_accounts) > 0 ? jsonencode(sort(formatlist(format("arn:aws:s3:::%s/%s/AWSLogs/%%s/*", var.s3_bucket_name, var.cloudtrail_logs_prefix), var.cloudtrail_accounts))) : jsonencode(format("arn:aws:s3:::%s/%s/AWSLogs/%s/*", var.s3_bucket_name, var.cloudtrail_logs_prefix, data.aws_caller_identity.current.account_id))}" - config_effect = "${(var.default_allow || var.allow_config) ? "Allow" : "Deny"}" - config_resources = "${length(var.config_accounts) > 0 ? jsonencode(sort(formatlist(format("arn:aws:s3:::%s/%s/AWSLogs/%%s/Config/*", var.s3_bucket_name, var.config_logs_prefix), var.config_accounts))) : jsonencode(format("arn:aws:s3:::%s/%s/AWSLogs/%s/Config/*", var.s3_bucket_name, var.config_logs_prefix, data.aws_caller_identity.current.account_id))}" - elb_effect = "${(var.default_allow || var.allow_elb) ? "Allow" : "Deny"}" - elb_principal = "${data.aws_elb_service_account.main.arn}" - elb_resources = "${length(var.elb_accounts) > 0 ? jsonencode(sort(formatlist(format("arn:aws:s3:::%s/%s/AWSLogs/%%s/*", var.s3_bucket_name, var.elb_logs_prefix), var.elb_accounts))) : jsonencode(format("arn:aws:s3:::%s/%s/AWSLogs/%s/*", var.s3_bucket_name, var.elb_logs_prefix, data.aws_caller_identity.current.account_id))}" - nlb_effect = "${(var.default_allow || var.allow_nlb) ? "Allow" : "Deny"}" - nlb_resources = "${length(var.nlb_accounts) > 0 ? jsonencode(sort(formatlist(format("arn:aws:s3:::%s/%s/AWSLogs/%%s/*", var.s3_bucket_name, var.nlb_logs_prefix), var.nlb_accounts))) : jsonencode(format("arn:aws:s3:::%s/%s/AWSLogs/%s/*", var.s3_bucket_name, var.nlb_logs_prefix, data.aws_caller_identity.current.account_id))}" - redshift_effect = "${(var.default_allow || var.allow_redshift) ? "Allow" : "Deny"}" - redshift_principal = "${format("arn:aws:iam::%s:user/logs", data.aws_redshift_service_account.main.id)}" - redshift_resources = "${jsonencode(format("arn:aws:s3:::%s/%s/*", var.s3_bucket_name, var.redshift_logs_prefix))}" + region = var.region + bucket_arn = format("arn:aws:s3:::%s", var.s3_bucket_name) + alb_principal = data.aws_elb_service_account.main.arn + alb_effect = var.default_allow || var.allow_alb ? "Allow" : "Deny" + alb_resources = jsonencode( + formatlist( + format("arn:aws:s3:::%s/%%s/*", var.s3_bucket_name), + var.alb_logs_prefixes, + ), + ) + cloudwatch_effect = var.default_allow || var.allow_cloudwatch ? "Allow" : "Deny" + cloudwatch_resources = jsonencode( + format( + "arn:aws:s3:::%s/%s/*", + var.s3_bucket_name, + var.cloudwatch_logs_prefix, + ), + ) + cloudtrail_effect = var.default_allow || var.allow_cloudtrail ? "Allow" : "Deny" + cloudtrail_resources = length(var.cloudtrail_accounts) > 0 ? jsonencode( + sort( + formatlist( + format( + "arn:aws:s3:::%s/%s/AWSLogs/%%s/*", + var.s3_bucket_name, + var.cloudtrail_logs_prefix, + ), + var.cloudtrail_accounts, + ), + ), + ) : jsonencode( + format( + "arn:aws:s3:::%s/%s/AWSLogs/%s/*", + var.s3_bucket_name, + var.cloudtrail_logs_prefix, + data.aws_caller_identity.current.account_id, + ), + ) + config_effect = var.default_allow || var.allow_config ? "Allow" : "Deny" + config_resources = length(var.config_accounts) > 0 ? jsonencode( + sort( + formatlist( + format( + "arn:aws:s3:::%s/%s/AWSLogs/%%s/Config/*", + var.s3_bucket_name, + var.config_logs_prefix, + ), + var.config_accounts, + ), + ), + ) : jsonencode( + format( + "arn:aws:s3:::%s/%s/AWSLogs/%s/Config/*", + var.s3_bucket_name, + var.config_logs_prefix, + data.aws_caller_identity.current.account_id, + ), + ) + elb_effect = var.default_allow || var.allow_elb ? "Allow" : "Deny" + elb_principal = data.aws_elb_service_account.main.arn + elb_resources = length(var.elb_accounts) > 0 ? jsonencode( + sort( + formatlist( + format( + "arn:aws:s3:::%s/%s/AWSLogs/%%s/*", + var.s3_bucket_name, + var.elb_logs_prefix, + ), + var.elb_accounts, + ), + ), + ) : jsonencode( + format( + "arn:aws:s3:::%s/%s/AWSLogs/%s/*", + var.s3_bucket_name, + var.elb_logs_prefix, + data.aws_caller_identity.current.account_id, + ), + ) + nlb_effect = var.default_allow || var.allow_nlb ? "Allow" : "Deny" + nlb_resources = length(var.nlb_accounts) > 0 ? jsonencode( + sort( + formatlist( + format( + "arn:aws:s3:::%s/%s/AWSLogs/%%s/*", + var.s3_bucket_name, + var.nlb_logs_prefix, + ), + var.nlb_accounts, + ), + ), + ) : jsonencode( + format( + "arn:aws:s3:::%s/%s/AWSLogs/%s/*", + var.s3_bucket_name, + var.nlb_logs_prefix, + data.aws_caller_identity.current.account_id, + ), + ) + redshift_effect = var.default_allow || var.allow_redshift ? "Allow" : "Deny" + redshift_principal = format( + "arn:aws:iam::%s:user/logs", + data.aws_redshift_service_account.main.id, + ) + redshift_resources = jsonencode( + format( + "arn:aws:s3:::%s/%s/*", + var.s3_bucket_name, + var.redshift_logs_prefix, + ), + ) } } resource "aws_s3_bucket" "aws_logs" { - bucket = "${var.s3_bucket_name}" - acl = "${var.s3_bucket_acl}" - region = "${var.region}" + bucket = var.s3_bucket_name + acl = var.s3_bucket_acl + region = var.region lifecycle_rule { id = "expire_all_logs" @@ -271,7 +368,7 @@ resource "aws_s3_bucket" "aws_logs" { enabled = true expiration { - days = "${var.s3_log_bucket_retention}" + days = var.s3_log_bucket_retention } } @@ -284,22 +381,22 @@ resource "aws_s3_bucket" "aws_logs" { } tags = { - Name = "${var.s3_bucket_name}" + Name = var.s3_bucket_name Automation = "Terraform" } } resource "aws_s3_bucket_policy" "bucket_policy" { - bucket = "${aws_s3_bucket.aws_logs.id}" - policy = "${data.template_file.bucket_policy.rendered}" + bucket = aws_s3_bucket.aws_logs.id + policy = data.template_file.bucket_policy.rendered } resource "aws_s3_bucket_public_access_block" "public_access_block" { - count = "${var.create_public_access_block ? 1 : 0}" + count = var.create_public_access_block ? 1 : 0 - depends_on = ["aws_s3_bucket_policy.bucket_policy"] + depends_on = [aws_s3_bucket_policy.bucket_policy] - bucket = "${aws_s3_bucket.aws_logs.id}" + bucket = aws_s3_bucket.aws_logs.id # Block new public ACLs and uploading public objects block_public_acls = true @@ -313,3 +410,4 @@ resource "aws_s3_bucket_public_access_block" "public_access_block" { # Retroactivley block public and cross-account access if bucket has public policies restrict_public_buckets = true } + diff --git a/outputs.tf b/outputs.tf index e132780..3bd66fa 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,19 +1,20 @@ output "aws_logs_bucket" { description = "S3 bucket containing AWS logs." - value = "${aws_s3_bucket.aws_logs.id}" + value = aws_s3_bucket.aws_logs.id } output "configs_logs_path" { description = "S3 path for Config logs." - value = "${var.config_logs_prefix}" + value = var.config_logs_prefix } output "elb_logs_path" { description = "S3 path for ELB logs." - value = "${var.elb_logs_prefix}" + value = var.elb_logs_prefix } output "redshift_logs_path" { description = "S3 path for RedShift logs." - value = "${var.redshift_logs_prefix}" + value = var.redshift_logs_prefix } + diff --git a/test/terraform_aws_logs_test.go b/test/terraform_aws_logs_test.go new file mode 100644 index 0000000..7ab5531 --- /dev/null +++ b/test/terraform_aws_logs_test.go @@ -0,0 +1,35 @@ +package test + +import ( + "fmt" + "strings" + "testing" + + "github.com/gruntwork-io/terratest/modules/aws" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/gruntwork-io/terratest/modules/terraform" +) + +func TestTerraformAwsLogs(t *testing.T) { + t.Parallel() + + expectedLogsBucket := fmt.Sprintf("terratest-aws-logs-%s", strings.ToLower(random.UniqueId())) + awsRegion := aws.GetRandomStableRegion(t, nil, nil) + + terraformOptions := &terraform.Options{ + TerraformDir: "../examples/simple/", + Vars: map[string]interface{}{ + "region": awsRegion, + "logs_bucket": expectedLogsBucket, + }, + EnvVars: map[string]string{ + "AWS_DEFAULT_REGION": awsRegion, + }, + } + + defer terraform.Destroy(t, terraformOptions) + terraform.InitAndApply(t, terraformOptions) + + // Empty logs_bucket before terraform destroy + aws.EmptyS3Bucket(t, awsRegion, expectedLogsBucket) +} diff --git a/variables.tf b/variables.tf index 8077b59..7175f70 100644 --- a/variables.tf +++ b/variables.tf @@ -1,142 +1,143 @@ variable "s3_bucket_name" { description = "S3 bucket to store AWS logs in." - type = "string" + type = string } variable "region" { description = "Region where the AWS S3 bucket will be created." - type = "string" + type = string } variable "s3_log_bucket_retention" { description = "Number of days to keep AWS logs around." default = 90 - type = "string" + type = string } variable "s3_bucket_acl" { description = "Set bucket ACL per [AWS S3 Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) list." default = "log-delivery-write" - type = "string" + type = string } variable "elb_logs_prefix" { description = "S3 prefix for ELB logs." default = "elb" - type = "string" + type = string } variable "alb_logs_prefixes" { description = "S3 key prefixes for ALB logs." default = ["alb"] - type = "list" + type = list(string) } variable "nlb_logs_prefix" { description = "S3 prefix for NLB logs." default = "nlb" - type = "string" + type = string } variable "cloudwatch_logs_prefix" { description = "S3 prefix for CloudWatch log exports." default = "cloudwatch" - type = "string" + type = string } variable "cloudtrail_logs_prefix" { description = "S3 prefix for CloudTrail logs." default = "cloudtrail" - type = "string" + type = string } variable "redshift_logs_prefix" { description = "S3 prefix for RedShift logs." default = "redshift" - type = "string" + type = string } variable "config_logs_prefix" { description = "S3 prefix for AWS Config logs." default = "config" - type = "string" + type = string } # Service Switches variable "default_allow" { description = "Whether all services included in this module should be allowed to write to the bucket by default. Alternatively select individual services. It's recommended to use the default bucket ACL of log-delivery-write." default = true - type = "string" + type = string } variable "allow_cloudtrail" { description = "Allow Cloudtrail service to log to bucket." default = false - type = "string" + type = string } variable "allow_cloudwatch" { description = "Allow Cloudwatch service to export logs to bucket." default = false - type = "string" + type = string } variable "allow_alb" { description = "Allow ALB service to log to bucket." default = false - type = "string" + type = string } variable "allow_nlb" { description = "Allow NLB service to log to bucket." default = false - type = "string" + type = string } variable "allow_config" { description = "Allow Config service to log to bucket." default = false - type = "string" + type = string } variable "allow_elb" { description = "Allow ELB service to log to bucket." default = false - type = "string" + type = string } variable "allow_redshift" { description = "Allow Redshift service to log to bucket." default = false - type = "string" + type = string } variable "create_public_access_block" { description = "Whether to create a public_access_block restricting public access to the bucket." default = true - type = "string" + type = string } variable "cloudtrail_accounts" { description = "List of accounts for CloudTrail logs. By default limits to the current account." default = [] - type = "list" + type = list(string) } variable "config_accounts" { description = "List of accounts for Config logs. By default limits to the current account." default = [] - type = "list" + type = list(string) } variable "elb_accounts" { description = "List of accounts for ELB logs. By default limits to the current account." default = [] - type = "list" + type = list(string) } variable "nlb_accounts" { description = "List of accounts for NLB logs. By default limits to the current account." default = [] - type = "list" + type = list(string) } + diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..ac97c6a --- /dev/null +++ b/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +}