From fcd2248dec5497e8986e85041e38848193fd40eb Mon Sep 17 00:00:00 2001 From: Loren Gordon Date: Mon, 1 Mar 2021 15:00:26 -0800 Subject: [PATCH 1/8] Accepts invite using new resource "aws_securityhub_invite_accepter" --- main.tf | 4 - modules/accepter/main.tf | 64 +------- modules/accepter/outputs.tf | 4 +- modules/accepter/security_hub_accepter.py | 170 ---------------------- modules/accepter/variables.tf | 15 -- outputs.tf | 2 +- variables.tf | 18 --- 7 files changed, 5 insertions(+), 272 deletions(-) delete mode 100644 modules/accepter/security_hub_accepter.py diff --git a/main.tf b/main.tf index 4c7f4e6..ebb301c 100644 --- a/main.tf +++ b/main.tf @@ -30,10 +30,6 @@ module "accept" { master_account_id = data.aws_caller_identity.master.account_id - profile = var.accepter_profile - role_arn = var.accepter_role_arn - region = var.accepter_region - depends_on = [ module.member ] diff --git a/modules/accepter/main.tf b/modules/accepter/main.tf index 1be09c6..4b899d8 100644 --- a/modules/accepter/main.tf +++ b/modules/accepter/main.tf @@ -1,63 +1,3 @@ -resource "null_resource" "accepter" { - provisioner "local-exec" { - command = join(" ", local.create) - } - - provisioner "local-exec" { - when = destroy - command = self.triggers.destroy_command - } - - provisioner "local-exec" { - when = destroy - command = "python -c 'import time; time.sleep(5)'" - } - - lifecycle { - ignore_changes = [triggers["destroy_command"]] - } - - triggers = { - destroy_command = join(" ", local.destroy) - } -} - -locals { - # Replace a terraform-aws-provider sts assumed role with the equivalent iam role, i.e: - # arn:aws:sts:::assumed-role// - # => - # arn:aws:iam:::role/ - # This allows a user to simply pass `role_arn = "${data.aws_caller_identity.this.arn}"` - role_arn = replace( - var.role_arn, - "/(.*):sts:(.*):assumed-role/(.*)/[0-9]*$/", - "$1:iam:$2:role/$3", - ) - - create = [ - "python", - "\"${path.module}/security_hub_accepter.py\"", - "--master-account-id", - "\"${var.master_account_id}\"", - "--profile", - "\"${var.profile}\"", - "--role-arn", - "\"${local.role_arn}\"", - "--region", - "\"${var.region}\"", - ] - - destroy = [ - "python", - "\"${path.module}/security_hub_accepter.py\"", - "--master-account-id", - "\"${var.master_account_id}\"", - "--remove-master", - "--profile", - "\"${var.profile}\"", - "--role-arn", - "\"${local.role_arn}\"", - "--region", - "\"${var.region}\"", - ] +resource "aws_securityhub_invite_accepter" "this" { + master_id = var.master_account_id } diff --git a/modules/accepter/outputs.tf b/modules/accepter/outputs.tf index e72f94c..bf0e88b 100644 --- a/modules/accepter/outputs.tf +++ b/modules/accepter/outputs.tf @@ -1,4 +1,4 @@ output "accepter" { - description = "Object containing SecurityHub accepter (null) resource" - value = null_resource.accepter + description = "Object containing SecurityHub accepter resource" + value = aws_securityhub_invite_accepter.this } diff --git a/modules/accepter/security_hub_accepter.py b/modules/accepter/security_hub_accepter.py deleted file mode 100644 index 84b4b48..0000000 --- a/modules/accepter/security_hub_accepter.py +++ /dev/null @@ -1,170 +0,0 @@ -"""Helper script to accept invite for cross-account RAM Share.""" -from __future__ import print_function - -import argparse -import collections -import logging -import os -import sys - -import botocore.credentials -import botocore.session - -DEFAULT_LOG_LEVEL = logging.INFO -LOG_LEVELS = collections.defaultdict( - lambda: DEFAULT_LOG_LEVEL, - { - "critical": logging.CRITICAL, - "error": logging.ERROR, - "warning": logging.WARNING, - "info": logging.INFO, - "debug": logging.DEBUG, - }, -) - -# Clear out any other root log handler -root = logging.getLogger() -if root.handlers: - for handler in root.handlers: - root.removeHandler(handler) - -logging.basicConfig( - format="%(asctime)s.%(msecs)03dZ [%(name)s][%(levelname)-5s]: %(message)s", - datefmt="%Y-%m-%dT%H:%M:%S", - level=LOG_LEVELS[os.environ.get("LOG_LEVEL", "").lower()], -) -log = logging.getLogger("security_hub_accepter.py") - - -class NoPendingInviteException(Exception): - """Custom exception for no pending invite.""" - - -class AssumeRoleProvider( - object -): # pylint: disable=useless-object-inheritance, too-few-public-methods - """Refreshable assume-role credential provider.""" - - METHOD = "assume-role" - - def __init__(self, fetcher): # noqa: D107 - self._fetcher = fetcher - - def load(self): - """Load refreshable credential.""" - return botocore.credentials.DeferredRefreshableCredentials( - self._fetcher.fetch_credentials, self.METHOD - ) - - -def filter_none_values(data): - """Return new dictionary excluding items where value was None.""" - return {k: v for k, v in data.items() if v is not None} - - -def assume_role( - session, - role_arn, - profile=None, - duration=3600, - session_name=None, - serial_number=None, -): # pylint: disable=too-many-arguments - """Assume a role with a refreshable credential.""" - fetcher = botocore.credentials.AssumeRoleCredentialFetcher( - session.create_client, - session.get_credentials(), - role_arn, - extra_args=filter_none_values( - { - "DurationSeconds": duration, - "RoleSessionName": session_name, - "SerialNumber": serial_number, - } - ), - cache=botocore.credentials.JSONFileCache(), - ) - role_session = botocore.session.Session(profile=profile) - role_session.register_component( - "credential_provider", - botocore.credentials.CredentialResolver([AssumeRoleProvider(fetcher)]), - ) - return role_session - - -def get_pending_invite_id(sechub, master_account_id): - """Get pending invite id.""" - invitations = sechub.list_invitations() - - for invite in invitations["Invitations"]: - invite_id = invite["InvitationId"] - if ( - invite["MemberStatus"] == "Invited" - and invite["AccountId"] == master_account_id - ): - return invite_id - - return None - - -def accept_pending_invite(sechub, master_account_id, invite_id): - """Accept pending invite.""" - sechub.accept_invitation(MasterId=master_account_id, InvitationId=invite_id) - - -def main( - master_account_id, remove_master=False, profile=None, role_arn=None, region=None -): - """Entrypoint for accept invite for cross-account RAM Share.""" - region = region or None - profile = profile or None - role_arn = role_arn or None - - session = botocore.session.Session(profile=profile) - session.set_default_client_config(botocore.client.Config(region_name=region)) - - if role_arn: - session = assume_role(session, role_arn, profile=profile) - - sechub = session.create_client("securityhub", region_name=region) - - if remove_master: - sechub.disassociate_from_master_account() - log.info("Disassociated member from master account: %s", master_account_id) - else: - invite_id = get_pending_invite_id(sechub, master_account_id) - - if not invite_id: - raise NoPendingInviteException("No pending invite found for Security Hub:") - - log.info("Found pending invite_id: %s", invite_id) - accept_pending_invite(sechub, master_account_id, invite_id) - log.info("Accepted invite from SecurityHub master: %s", master_account_id) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument( - "--master-account-id", help="Account ID of the SecurityHub master" - ) - parser.add_argument( - "--remove-master", - action="store_true", - help="Dissasociate from the SecurityHub master", - ) - parser.add_argument( - "--profile", default=None, help="Profile to use when setting up the AWS session" - ) - parser.add_argument( - "--role-arn", - default=None, - help="ARN of a role to assume with permissions to SecurityHub", - ) - parser.add_argument( - "--region", - default=None, - help="Region in which to look for the SecurityHub invite", - ) - - args = parser.parse_args() - sys.exit(main(**vars(args))) diff --git a/modules/accepter/variables.tf b/modules/accepter/variables.tf index 84bb54c..13892e6 100644 --- a/modules/accepter/variables.tf +++ b/modules/accepter/variables.tf @@ -2,18 +2,3 @@ variable "master_account_id" { description = "Account ID of the AWS SecurityHub master account that sent the invite" type = string } - -variable "profile" { - description = "Used by null_resource to establish botocore session" - type = string -} - -variable "role_arn" { - description = "Used by null_resource to assume a role in the accepter account" - type = string -} - -variable "region" { - description = "Used by null_resource to establish botocore client" - type = string -} diff --git a/outputs.tf b/outputs.tf index 591fec1..bfbcc09 100644 --- a/outputs.tf +++ b/outputs.tf @@ -9,7 +9,7 @@ output "member" { } output "accept" { - description = "Object containing the SecurityHub (null) accepter resource" + description = "Object containing the SecurityHub accepter resource" value = local.cross_account ? module.accept[0].accepter : null } diff --git a/variables.tf b/variables.tf index b23164c..44914d3 100644 --- a/variables.tf +++ b/variables.tf @@ -25,21 +25,3 @@ variable "member_email" { type = string default = null } - -variable "accepter_profile" { - description = "(Optional) Used by null_resource accepter to establish botocore session. Required for the cross-account SecurityHub member accept workflow" - type = string - default = "" -} - -variable "accepter_role_arn" { - description = "(Optional) Used by null_resource accepter to assume a role in the accepter account. Required for the cross-account SecurityHub member accept workflow" - type = string - default = "" -} - -variable "accepter_region" { - description = "(Optional) Used by null_resource accepter to establish botocore client. Required for the cross-account SecurityHub member accept workflow" - type = string - default = "" -} From 4ad494fabb78d01103e3a14778dd5cc5f03ba948 Mon Sep 17 00:00:00 2001 From: Loren Gordon Date: Mon, 1 Mar 2021 15:01:03 -0800 Subject: [PATCH 2/8] Lets terraform handle invite propagation and retries --- modules/member/main.tf | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modules/member/main.tf b/modules/member/main.tf index 3986d19..6c0748d 100644 --- a/modules/member/main.tf +++ b/modules/member/main.tf @@ -2,10 +2,4 @@ resource "aws_securityhub_member" "this" { account_id = var.account_id email = var.email invite = true - - # The invite sometimes takes a few seconds to register before it can be accepted in the target account, - # so we pause for 5 seconds to let the invite propagate - provisioner "local-exec" { - command = "python -c 'import time; time.sleep(5)'" - } } From 8eca040ce3a8fe5faeb2b1b47142028b09001964 Mon Sep 17 00:00:00 2001 From: Loren Gordon Date: Mon, 1 Mar 2021 15:01:21 -0800 Subject: [PATCH 3/8] Sets minimum aws provider version --- versions.tf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/versions.tf b/versions.tf index 6b6318d..966e9bd 100644 --- a/versions.tf +++ b/versions.tf @@ -1,3 +1,10 @@ terraform { required_version = ">= 0.13" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29.0" + } + } } From 21a106b6e13fe2136d9ba8e2f855eb4b68ea3c25 Mon Sep 17 00:00:00 2001 From: Loren Gordon Date: Tue, 2 Mar 2021 12:07:44 -0800 Subject: [PATCH 4/8] Updates tests to work with aws_securityhub_invite_accepter --- .gitignore | 7 +++---- tests/securityhub_cross_account/main.tf | 6 +----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index f325ca8..724e9c9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,9 +15,8 @@ tardigrade-ci/ .tardigrade-ci -# eclint - -.git/ - # terratest tests/go.* + +# terraform lock file +.terraform.lock.hcl diff --git a/tests/securityhub_cross_account/main.tf b/tests/securityhub_cross_account/main.tf index f13b9cb..41bf57e 100644 --- a/tests/securityhub_cross_account/main.tf +++ b/tests/securityhub_cross_account/main.tf @@ -17,9 +17,7 @@ module "securityhub_member" { aws.master = aws.resource-owner } - member_email = var.member_email - accepter_region = data.aws_region.current.name - accepter_profile = "resource-member" + member_email = var.member_email standard_subscription_arns = [ "arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0", @@ -31,8 +29,6 @@ module "securityhub_member" { ] } -data "aws_region" "current" {} - output "securityhub" { value = module.securityhub_member } From 443b6bb3371eb330dd4e9a93b25340daf77e869b Mon Sep 17 00:00:00 2001 From: Loren Gordon Date: Tue, 2 Mar 2021 14:29:42 -0800 Subject: [PATCH 5/8] Moves cross-account workflow into separate module This eliminates the extra "provider" when *not* using the cross- account workflow. It also streamlines the inputs for each use case. --- README.md | 17 +++------ main.tf | 42 ---------------------- modules/accepter/README.md | 7 ++-- modules/cross-account-member/README.md | 37 +++++++++++++++++++ modules/cross-account-member/main.tf | 44 +++++++++++++++++++++++ modules/cross-account-member/outputs.tf | 24 +++++++++++++ modules/cross-account-member/variables.tf | 26 ++++++++++++++ modules/cross-account-member/versions.tf | 10 ++++++ outputs.tf | 10 ------ variables.tf | 6 ---- 10 files changed, 148 insertions(+), 75 deletions(-) create mode 100644 modules/cross-account-member/README.md create mode 100644 modules/cross-account-member/main.tf create mode 100644 modules/cross-account-member/outputs.tf create mode 100644 modules/cross-account-member/variables.tf create mode 100644 modules/cross-account-member/versions.tf diff --git a/README.md b/README.md index 484ab0d..a4d11c1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # terraform-aws-tardigrade-security-hub -Terraform module to enable SecurityHub in a child account and link it -to a pre-existing SecurityHub instance in the parent account +Terraform module to enable and configure SecurityHub. The module supports independent +accounts with the top-level module, and the cross-account invite/accept workflow with +the `modules/cross-account-member` module. ## Testing You can find example implementations of this module in the tests folder. This module @@ -16,23 +17,17 @@ Note: the implementation `tests/create_securityhub_member` will require you to p | Name | Version | |------|---------| | terraform | >= 0.13 | +| aws | >= 3.29.0 | ## Providers -| Name | Version | -|------|---------| -| aws | n/a | -| aws.master | n/a | +No provider. ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| accepter\_profile | (Optional) Used by null\_resource accepter to establish botocore session. Required for the cross-account SecurityHub member accept workflow | `string` | `""` | no | -| accepter\_region | (Optional) Used by null\_resource accepter to establish botocore client. Required for the cross-account SecurityHub member accept workflow | `string` | `""` | no | -| accepter\_role\_arn | (Optional) Used by null\_resource accepter to assume a role in the accepter account. Required for the cross-account SecurityHub member accept workflow | `string` | `""` | no | | action\_targets | Schema list of SecurityHub action targets. |
list(object({
name = string
description = string
identifer = string
}))
| `[]` | no | -| member\_email | (Optional) Email address associated with the member account. Required for the cross-account SecurityHub member invite workflow | `string` | `null` | no | | product\_subscription\_arns | List of product arns to subscribe to. See https://www.terraform.io/docs/providers/aws/r/securityhub_product_subscription.html | `list(string)` | `[]` | no | | standard\_subscription\_arns | List of standard arns to subscribe to. See https://www.terraform.io/docs/providers/aws/r/securityhub_standards_subscription.html | `list(string)` | `[]` | no | @@ -40,10 +35,8 @@ Note: the implementation `tests/create_securityhub_member` will require you to p | Name | Description | |------|-------------| -| accept | Object containing the SecurityHub (null) accepter resource | | account | Object containing the SecurityHub account resource | | action\_targets | Object containing the SecurityHub action targets resources | -| member | Object containing the SecurityHub member resource | | subscriptions | Object containing the SecurityHub subscriptions resources | diff --git a/main.tf b/main.tf index ebb301c..f15b60d 100644 --- a/main.tf +++ b/main.tf @@ -1,40 +1,8 @@ -provider "aws" { - alias = "master" -} - # Enable SecurityHub module "account" { source = "./modules/account" } -# Send invite from master -module "member" { - source = "./modules/member" - count = local.cross_account ? 1 : 0 - providers = { - aws = aws.master - } - - account_id = data.aws_caller_identity.this.account_id - email = var.member_email - - depends_on = [ - module.account - ] -} - -# Accept invite -module "accept" { - source = "./modules/accepter" - count = local.cross_account ? 1 : 0 - - master_account_id = data.aws_caller_identity.master.account_id - - depends_on = [ - module.member - ] -} - # Manage subscriptions module "subscriptions" { source = "./modules/subscriptions" @@ -56,13 +24,3 @@ module "action_targets" { description = each.value.description identifier = each.value.identifier } - -locals { - cross_account = data.aws_caller_identity.this.account_id != data.aws_caller_identity.master.account_id -} - -data "aws_caller_identity" "this" {} - -data "aws_caller_identity" "master" { - provider = aws.master -} diff --git a/modules/accepter/README.md b/modules/accepter/README.md index 45647f8..3df8866 100644 --- a/modules/accepter/README.md +++ b/modules/accepter/README.md @@ -9,21 +9,18 @@ No requirements. | Name | Version | |------|---------| -| null | n/a | +| aws | n/a | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | master\_account\_id | Account ID of the AWS SecurityHub master account that sent the invite | `string` | n/a | yes | -| profile | Used by null\_resource to establish botocore session | `string` | n/a | yes | -| region | Used by null\_resource to establish botocore client | `string` | n/a | yes | -| role\_arn | Used by null\_resource to assume a role in the accepter account | `string` | n/a | yes | ## Outputs | Name | Description | |------|-------------| -| accepter | Object containing SecurityHub accepter (null) resource | +| accepter | Object containing SecurityHub accepter resource | diff --git a/modules/cross-account-member/README.md b/modules/cross-account-member/README.md new file mode 100644 index 0000000..e741eed --- /dev/null +++ b/modules/cross-account-member/README.md @@ -0,0 +1,37 @@ +# terraform-aws-tardigrade-security-hub/cross-account-member + + +## Requirements + +| Name | Version | +|------|---------| +| terraform | >= 0.13 | +| aws | >= 3.29.0 | + +## Providers + +| Name | Version | +|------|---------| +| aws | >= 3.29.0 | +| aws.administrator | >= 3.29.0 | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| member\_email | Email address associated with the member account. Required for the cross-account SecurityHub member invite workflow | `string` | n/a | yes | +| action\_targets | Schema list of SecurityHub action targets. |
list(object({
name = string
description = string
identifer = string
}))
| `[]` | no | +| product\_subscription\_arns | List of product arns to subscribe to. See https://www.terraform.io/docs/providers/aws/r/securityhub_product_subscription.html | `list(string)` | `[]` | no | +| standard\_subscription\_arns | List of standard arns to subscribe to. See https://www.terraform.io/docs/providers/aws/r/securityhub_standards_subscription.html | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| accepter | Object containing the SecurityHub accepter resource | +| account | Object containing the SecurityHub account resource | +| action\_targets | Object containing the SecurityHub action targets resources | +| member | Object containing the SecurityHub member resource | +| subscriptions | Object containing the SecurityHub subscriptions resources | + + diff --git a/modules/cross-account-member/main.tf b/modules/cross-account-member/main.tf new file mode 100644 index 0000000..eda9cb2 --- /dev/null +++ b/modules/cross-account-member/main.tf @@ -0,0 +1,44 @@ +provider "aws" { + alias = "administrator" +} + +# Enables/configures Security Hub in member account +module "account" { + source = "../../" + + action_targets = var.action_targets + product_subscription_arns = var.product_subscription_arns + standard_subscription_arns = var.standard_subscription_arns +} + +# Send invite from administrator account +module "member" { + source = "../member" + providers = { + aws = aws.administrator + } + + account_id = data.aws_caller_identity.this.account_id + email = var.member_email + + depends_on = [ + module.account + ] +} + +# Accept invite +module "accept" { + source = "../accepter" + + master_account_id = data.aws_caller_identity.administrator.account_id + + depends_on = [ + module.member + ] +} + +data "aws_caller_identity" "this" {} + +data "aws_caller_identity" "administrator" { + provider = aws.administrator +} diff --git a/modules/cross-account-member/outputs.tf b/modules/cross-account-member/outputs.tf new file mode 100644 index 0000000..624b223 --- /dev/null +++ b/modules/cross-account-member/outputs.tf @@ -0,0 +1,24 @@ +output "account" { + description = "Object containing the SecurityHub account resource" + value = module.account.account +} + +output "member" { + description = "Object containing the SecurityHub member resource" + value = module.member.member +} + +output "accepter" { + description = "Object containing the SecurityHub accepter resource" + value = module.accept.accepter +} + +output "subscriptions" { + description = "Object containing the SecurityHub subscriptions resources" + value = module.account.subscriptions +} + +output "action_targets" { + description = "Object containing the SecurityHub action targets resources" + value = module.account.action_targets +} diff --git a/modules/cross-account-member/variables.tf b/modules/cross-account-member/variables.tf new file mode 100644 index 0000000..36e20bd --- /dev/null +++ b/modules/cross-account-member/variables.tf @@ -0,0 +1,26 @@ +variable "member_email" { + description = "Email address associated with the member account. Required for the cross-account SecurityHub member invite workflow" + type = string +} + +variable "action_targets" { + description = "Schema list of SecurityHub action targets." + type = list(object({ + name = string + description = string + identifer = string + })) + default = [] +} + +variable "product_subscription_arns" { + description = "List of product arns to subscribe to. See https://www.terraform.io/docs/providers/aws/r/securityhub_product_subscription.html" + type = list(string) + default = [] +} + +variable "standard_subscription_arns" { + description = "List of standard arns to subscribe to. See https://www.terraform.io/docs/providers/aws/r/securityhub_standards_subscription.html" + type = list(string) + default = [] +} diff --git a/modules/cross-account-member/versions.tf b/modules/cross-account-member/versions.tf new file mode 100644 index 0000000..966e9bd --- /dev/null +++ b/modules/cross-account-member/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29.0" + } + } +} diff --git a/outputs.tf b/outputs.tf index bfbcc09..ae3247f 100644 --- a/outputs.tf +++ b/outputs.tf @@ -3,16 +3,6 @@ output "account" { value = module.account.account } -output "member" { - description = "Object containing the SecurityHub member resource" - value = local.cross_account ? module.member[0].member : null -} - -output "accept" { - description = "Object containing the SecurityHub accepter resource" - value = local.cross_account ? module.accept[0].accepter : null -} - output "subscriptions" { description = "Object containing the SecurityHub subscriptions resources" value = module.subscriptions diff --git a/variables.tf b/variables.tf index 44914d3..885497d 100644 --- a/variables.tf +++ b/variables.tf @@ -19,9 +19,3 @@ variable "product_subscription_arns" { type = list(string) default = [] } - -variable "member_email" { - description = "(Optional) Email address associated with the member account. Required for the cross-account SecurityHub member invite workflow" - type = string - default = null -} From d504d2f3c8ac0142c95d7fdef89d4f3f1eb5332a Mon Sep 17 00:00:00 2001 From: Loren Gordon Date: Tue, 2 Mar 2021 14:33:57 -0800 Subject: [PATCH 6/8] Updates tests to account for the new dedicated workflows --- tests/securityhub_cross_account/main.tf | 10 +++++----- tests/securityhub_cross_account/prereq/main.tf | 11 ----------- tests/securityhub_same_account/main.tf | 11 ----------- 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/tests/securityhub_cross_account/main.tf b/tests/securityhub_cross_account/main.tf index 41bf57e..fce6db6 100644 --- a/tests/securityhub_cross_account/main.tf +++ b/tests/securityhub_cross_account/main.tf @@ -9,12 +9,12 @@ provider "aws" { profile = "resource-owner" } -module "securityhub_member" { - source = "../../" +module "securityhub" { + source = "../../modules/cross-account-member" providers = { - aws = aws - aws.master = aws.resource-owner + aws = aws + aws.administrator = aws.resource-owner } member_email = var.member_email @@ -30,5 +30,5 @@ module "securityhub_member" { } output "securityhub" { - value = module.securityhub_member + value = module.securityhub } diff --git a/tests/securityhub_cross_account/prereq/main.tf b/tests/securityhub_cross_account/prereq/main.tf index 9ade683..ecfeb59 100644 --- a/tests/securityhub_cross_account/prereq/main.tf +++ b/tests/securityhub_cross_account/prereq/main.tf @@ -1,19 +1,8 @@ provider "aws" { region = "us-east-1" - profile = "resource-member" -} - -provider "aws" { - region = "us-east-1" - alias = "resource-owner" profile = "resource-owner" } module "securityhub_owner" { source = "../../../" - - providers = { - aws = aws.resource-owner - aws.master = aws.resource-owner - } } diff --git a/tests/securityhub_same_account/main.tf b/tests/securityhub_same_account/main.tf index f6d4ca2..512c14e 100644 --- a/tests/securityhub_same_account/main.tf +++ b/tests/securityhub_same_account/main.tf @@ -3,20 +3,9 @@ provider "aws" { profile = "resource-owner" } -provider "aws" { - region = "us-east-1" - alias = "resource-owner" - profile = "resource-owner" -} - module "securityhub" { source = "../../" - providers = { - aws = aws - aws.master = aws.resource-owner - } - standard_subscription_arns = [ "arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0", "arn:aws:securityhub:us-east-1::standards/pci-dss/v/3.2.1", From 13bd9bab576b58756db916f87925fb8a10497e23 Mon Sep 17 00:00:00 2001 From: Loren Gordon Date: Tue, 2 Mar 2021 14:42:41 -0800 Subject: [PATCH 7/8] Updates changelog for v2 release and adds missing releases --- CHANGELOG.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40e2664..c71c213 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,60 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +### 2.0.0 + +**Released**: 2021.03.03 + +**Commit Delta**: [Change from 1.0.0 release](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/compare/1.0.0...2.0.0) + +**Summary**: + +* Replaces python accepter with new resource, `aws_securityhub_invite_accepter`. + See [PR #60](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/pull/60). +* Moves cross-account workflow into separate module. This eliminates the extra + "provider" when *not* using the cross-account workflow. It also streamlines + the inputs for each use case. See [PR #60](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/pull/60). +* Renames the `master` provider to `administrator` for the cross-account workflow. + See [PR #60](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/pull/60). + +### 1.0.0 + +**Released**: 2020.10.07 + +**Commit Delta**: [Change from 0.0.3 release](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/compare/0.0.3...1.0.0) + +**Summary**: + +* Splits resources into submodules to support separate master/member workflows. + See [PR #44](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/pull/44). + +### 0.0.3 + +**Released**: 2020.05.14 + +**Commit Delta**: [Change from 0.0.2 release](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/compare/0.0.2...0.0.3) + +**Summary**: + +* Avoids error, "Cannot include a null value in a string template". + See [PR #16](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/pull/16). + +### 0.0.2 + +**Released**: 2020.05.13 + +**Commit Delta**: [Change from 0.0.1 release](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/compare/0.0.1...0.0.2) + +**Summary**: + +* Passes profile and region through the refreshable credential properly. + See [PR #15](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/pull/15). + ### 0.0.1 **Released**: 2020.05.08 -**Commit Delta**: [Change from 1.0.4 release](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/compare/0.0.0...0.0.1) +**Commit Delta**: [Change from 0.0.0 release](https://github.com/plus3it/terraform-aws-tardigrade-security-hub/compare/0.0.0...0.0.1) **Summary**: From b87bd974760aeb08b6474cefcac2c37c39345b88 Mon Sep 17 00:00:00 2001 From: Loren Gordon Date: Tue, 2 Mar 2021 14:34:08 -0800 Subject: [PATCH 8/8] Bumps version to 2.0.0 --- .bumpversion.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index fab32b7..b49e513 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.0.0 +current_version = 2.0.0 commit = True message = Bumps version to {new_version} tag = False