diff --git a/modules/externalrole/README.md b/modules/externalrole/README.md new file mode 100644 index 0000000..d9f28eb --- /dev/null +++ b/modules/externalrole/README.md @@ -0,0 +1,74 @@ +# Observe AWS External Role + +This module configures an IAM role that can be assumed by Observe. + +## Usage + +```hcl +resource "random_pet" "this" {} + +data "observe_cloud_info" {} + +data "observe_workspace" "default" { + name = "Default" +} + +resource "observe_datastream" "example" { + workspace = data.observe_workspace.default.oid + name = random_pet.this.id +} + +module "external_role" { + source = "observeinc/collection/aws//modules/externalrole" + name = random_pet.this.id + + observe_aws_account_id = data.observe_cloud_info.account_id + datastream_ids = [observe_datastream.example.id] + allowed_actions = [ + "cloudwatch:ListMetrics", + "cloudwatch:GetMetricsData", + "tags:GetResources", + ] +} + +``` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allowed\_actions](#input\_allowed\_actions) | Set of IAM actions external entity is allowed to perform. | `list(string)` | n/a | yes | +| [datastream\_ids](#input\_datastream\_ids) | Observe datastreams collected data is intended for. | `list(string)` | n/a | yes | +| [name](#input\_name) | Name for IAM role. | `string` | n/a | yes | +| [observe\_aws\_account\_id](#input\_observe\_aws\_account\_id) | AWS account ID for Observe tenant | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [role](#output\_role) | IAM role to be assummed by Observe | + diff --git a/modules/externalrole/main.tf b/modules/externalrole/main.tf new file mode 100644 index 0000000..31f5229 --- /dev/null +++ b/modules/externalrole/main.tf @@ -0,0 +1,39 @@ +resource "aws_iam_role" "this" { + name = var.name + + assume_role_policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Action = "sts:AssumeRole", + Effect = "Allow", + Principal = { + AWS = [ + "arn:aws:iam::${var.observe_aws_account_id}:root" + ] + }, + Condition = { + StringEquals = { + "sts:ExternalId" = var.datastream_ids + } + } + } + ] + }) + + inline_policy { + name = "allowed" + + policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Action = var.allowed_actions + + Effect = "Allow", + Resource = "*" + } + ] + }) + } +} diff --git a/modules/externalrole/outputs.tf b/modules/externalrole/outputs.tf new file mode 100644 index 0000000..68e58de --- /dev/null +++ b/modules/externalrole/outputs.tf @@ -0,0 +1,4 @@ +output "role" { + description = "IAM role to be assummed by Observe" + value = aws_iam_role.this +} diff --git a/modules/externalrole/tests/externalrole.tftest.hcl b/modules/externalrole/tests/externalrole.tftest.hcl new file mode 100644 index 0000000..6a61aa7 --- /dev/null +++ b/modules/externalrole/tests/externalrole.tftest.hcl @@ -0,0 +1,16 @@ +run "setup" { + module { + source = "../testing/setup" + } +} + +run "install" { + variables { + name = run.setup.id + observe_aws_account_id = "158067661102" + datastream_ids = ["4100001"] + allowed_actions = [ + "cloudwatch:ListMetrics", + ] + } +} diff --git a/modules/externalrole/variables.tf b/modules/externalrole/variables.tf new file mode 100644 index 0000000..9e5b59d --- /dev/null +++ b/modules/externalrole/variables.tf @@ -0,0 +1,49 @@ +variable "name" { + type = string + nullable = false + description = <<-EOF + Name for IAM role. + EOF + + validation { + condition = length(var.name) <= 64 + error_message = "Name must be under 64 characters." + } +} + +variable "observe_aws_account_id" { + description = "AWS account ID for Observe tenant" + type = string + nullable = false + + validation { + condition = can(regex("^\\d{12}$", var.observe_aws_account_id)) + error_message = "Account ID must have 12 digits." + } +} + +variable "datastream_ids" { + description = <<-EOF + Observe datastreams collected data is intended for. + EOF + type = list(string) + nullable = false + + validation { + condition = length(var.datastream_ids) > 0 + error_message = "At least one datastream must be provided." + } +} + +variable "allowed_actions" { + description = <<-EOF + Set of IAM actions external entity is allowed to perform. + EOF + type = list(string) + nullable = false + + validation { + condition = length(var.allowed_actions) > 0 + error_message = "At least one action must be provided." + } +} diff --git a/modules/externalrole/versions.tf b/modules/externalrole/versions.tf new file mode 100644 index 0000000..4c505f8 --- /dev/null +++ b/modules/externalrole/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.3" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +}