diff --git a/README.md b/README.md index 365227f..95cc8b5 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,12 @@ module "appsync" { endpoint = "https://search-my-domain.eu-west-1.es.amazonaws.com" region = "eu-west-1" } + + opensearchservice1 = { + type = "AMAZON_OPENSEARCH_SERVICE" + endpoint = "https://opensearch-my-domain.eu-west-1.es.amazonaws.com" + region = "eu-west-1" + } } resolvers = { @@ -185,6 +191,7 @@ No modules. | [logs\_role\_tags](#input\_logs\_role\_tags) | Map of tags to add to Cloudwatch logs IAM role | `map(string)` | `{}` | no | | [name](#input\_name) | Name of GraphQL API | `string` | `""` | no | | [openid\_connect\_config](#input\_openid\_connect\_config) | Nested argument containing OpenID Connect configuration. | `map(string)` | `{}` | no | +| [opensearchservice\_allowed\_actions](#input\_opensearchservice\_allowed\_actions) | List of allowed IAM actions for datasources type AMAZON\_OPENSEARCH\_SERVICE | `list(string)` |
[| no | | [resolver\_caching\_ttl](#input\_resolver\_caching\_ttl) | Default caching TTL for resolvers when caching is enabled | `number` | `60` | no | | [resolvers](#input\_resolvers) | Map of resolvers to create | `any` | `{}` | no | | [schema](#input\_schema) | The schema definition, in GraphQL schema language format. Terraform cannot perform drift detection of this configuration. | `string` | `""` | no | diff --git a/examples/complete/main.tf b/examples/complete/main.tf index d921e5a..48c703e 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -213,6 +213,15 @@ module "appsync" { endpoint = "https://search-my-domain.eu-west-1.es.amazonaws.com" region = "eu-west-1" } + + # Opensearch Service support has not been finished & tested + opensearchservice1 = { + type = "AMAZON_OPENSEARCH_SERVICE" + + # Note: dynamic references (module.opensearchservice1.id) do not work do not work unless you create this resource in advance + endpoint = "https://search-my-domain-2.eu-west-1.es.amazonaws.com" + region = "eu-west-1" + } } resolvers = { diff --git a/iam.tf b/iam.tf index b878553..4758570 100644 --- a/iam.tf +++ b/iam.tf @@ -1,7 +1,7 @@ data "aws_partition" "this" {} locals { - service_roles_with_policies = var.create_graphql_api ? { for k, v in var.datasources : k => v if contains(["AWS_LAMBDA", "AMAZON_DYNAMODB", "AMAZON_ELASTICSEARCH"], v.type) && tobool(lookup(v, "create_service_role", true)) } : {} + service_roles_with_policies = var.create_graphql_api ? { for k, v in var.datasources : k => v if contains(["AWS_LAMBDA", "AMAZON_DYNAMODB", "AMAZON_ELASTICSEARCH", "AMAZON_OPENSEARCH_SERVICE"], v.type) && tobool(lookup(v, "create_service_role", true)) } : {} service_roles_with_policies_lambda = { for k, v in local.service_roles_with_policies : k => merge(v, { @@ -39,10 +39,23 @@ locals { } ) if v.type == "AMAZON_ELASTICSEARCH" } + service_roles_with_policies_opensearchservice = { for k, v in local.service_roles_with_policies : k => merge(v, + { + policy_statements = { + opensearchservice = { + effect = "Allow" + actions = lookup(v, "policy_actions", null) == null ? var.opensearchservice_allowed_actions : v.policy_actions + resources = [format("arn:${data.aws_partition.this.partition}:es:%v::domain/%v/*", v.region, v.endpoint)] + } + } + } + ) if v.type == "AMAZON_OPENSEARCH_SERVICE" } + service_roles_with_specific_policies = merge( local.service_roles_with_policies_lambda, local.service_roles_with_policies_dynamodb, local.service_roles_with_policies_elasticsearch, + local.service_roles_with_policies_opensearchservice, ) } diff --git a/main.tf b/main.tf index be4398c..9142596 100644 --- a/main.tf +++ b/main.tf @@ -144,7 +144,7 @@ resource "aws_appsync_datasource" "this" { name = each.key type = each.value.type description = lookup(each.value, "description", null) - service_role_arn = lookup(each.value, "service_role_arn", tobool(lookup(each.value, "create_service_role", contains(["AWS_LAMBDA", "AMAZON_DYNAMODB", "AMAZON_ELASTICSEARCH"], each.value.type))) ? aws_iam_role.service_role[each.key].arn : null) + service_role_arn = lookup(each.value, "service_role_arn", tobool(lookup(each.value, "create_service_role", contains(["AWS_LAMBDA", "AMAZON_DYNAMODB", "AMAZON_ELASTICSEARCH", "AMAZON_OPENSEARCH_SERVICE"], each.value.type))) ? aws_iam_role.service_role[each.key].arn : null) dynamic "http_config" { for_each = each.value.type == "HTTP" ? [true] : [] @@ -180,6 +180,15 @@ resource "aws_appsync_datasource" "this" { region = lookup(each.value, "region", null) } } + + dynamic "opensearchservice_config" { + for_each = each.value.type == "AMAZON_OPENSEARCH_SERVICE" ? [true] : [] + + content { + endpoint = each.value.endpoint + region = lookup(each.value, "region", null) + } + } } # Resolvers diff --git a/variables.tf b/variables.tf index 8471fa7..9ee386c 100644 --- a/variables.tf +++ b/variables.tf @@ -230,6 +230,12 @@ variable "elasticsearch_allowed_actions" { default = ["es:ESHttpDelete", "es:ESHttpHead", "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut"] } +variable "opensearchservice_allowed_actions" { + description = "List of allowed IAM actions for datasources type AMAZON_OPENSEARCH_SERVICE" + type = list(string) + default = ["es:ESHttpDelete", "es:ESHttpHead", "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut"] +} + variable "iam_permissions_boundary" { description = "ARN for iam permissions boundary" type = string diff --git a/wrappers/main.tf b/wrappers/main.tf index 4613965..219c423 100644 --- a/wrappers/main.tf +++ b/wrappers/main.tf @@ -36,6 +36,7 @@ module "wrapper" { lambda_allowed_actions = try(each.value.lambda_allowed_actions, var.defaults.lambda_allowed_actions, ["lambda:invokeFunction"]) dynamodb_allowed_actions = try(each.value.dynamodb_allowed_actions, var.defaults.dynamodb_allowed_actions, ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:DeleteItem", "dynamodb:UpdateItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem"]) elasticsearch_allowed_actions = try(each.value.elasticsearch_allowed_actions, var.defaults.elasticsearch_allowed_actions, ["es:ESHttpDelete", "es:ESHttpHead", "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut"]) + opensearchservice_allowed_actions = try(each.value.opensearchservice_allowed_actions, var.defaults.opensearchservice_allowed_actions, ["es:ESHttpDelete", "es:ESHttpHead", "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut"]) iam_permissions_boundary = try(each.value.iam_permissions_boundary, var.defaults.iam_permissions_boundary, null) direct_lambda_request_template = try(each.value.direct_lambda_request_template, var.defaults.direct_lambda_request_template, <<-EOF {
"es:ESHttpDelete",
"es:ESHttpHead",
"es:ESHttpGet",
"es:ESHttpPost",
"es:ESHttpPut"
]