From 158b7d79ece06815cea20e64aa5bd15a5b197efe Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Mon, 27 May 2019 19:04:48 +0300 Subject: [PATCH] Added VPC Endpoints for SNS, Cloudtrail, ELB, Cloudwatch (#269) --- README.md | 40 ++++- .../issue-108-route-already-exists/main.tf | 1 - main.tf | 134 ++++++++++++++++ outputs.tf | 90 +++++++++++ variables.tf | 144 ++++++++++++++++++ 5 files changed, 407 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4754b333f..0f3be4eee 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,9 @@ These types of resources are supported: * [VPN Gateway](https://www.terraform.io/docs/providers/aws/r/vpn_gateway.html) * [VPC Endpoint](https://www.terraform.io/docs/providers/aws/r/vpc_endpoint.html): * Gateway: S3, DynamoDB - * Interface: EC2, SSM, EC2 Messages, SSM Messages, SQS, ECR API, ECR DKR, API Gateway, KMS, ECS, ECS Agent, ECS Telemetry + * Interface: EC2, SSM, EC2 Messages, SSM Messages, SQS, ECR API, ECR DKR, API Gateway, KMS, + ECS, ECS Agent, ECS Telemetry, SNS, CloudWatch(Monitoring, Logs, Events), Elastic Load Balancing, + CloudTrail * [RDS DB Subnet Group](https://www.terraform.io/docs/providers/aws/r/db_subnet_group.html) * [ElastiCache Subnet Group](https://www.terraform.io/docs/providers/aws/r/elasticache_subnet_group.html) * [Redshift Subnet Group](https://www.terraform.io/docs/providers/aws/r/redshift_subnet_group.html) @@ -263,6 +265,24 @@ Sometimes it is handy to have public access to Redshift clusters (for example if | ecs\_telemetry\_endpoint\_private\_dns\_enabled | Whether or not to associate a private hosted zone with the specified VPC for ECS Telemetry endpoint | string | `"false"` | no | | ecs\_telemetry\_endpoint\_security\_group\_ids | The ID of one or more security groups to associate with the network interface for ECS Telemetry endpoint | list | `[]` | no | | ecs\_telemetry\_endpoint\_subnet\_ids | The ID of one or more subnets in which to create a network interface for ECS Telemetry endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used. | list | `[]` | no | +| sns\_endpoint\_private\_dns\_enabled | Whether or not to associate a private hosted zone with the specified VPC for SNS endpoint | string | `"false"` | no | +| sns\_endpoint\_security\_group\_ids | The ID of one or more security groups to associate with the network interface for SNS endpoint | list | `[]` | no | +| sns\_endpoint\_subnet\_ids | The ID of one or more subnets in which to create a network interface for SNS endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used. | list | `[]` | no | +| cloudtrail\_endpoint\_private\_dns\_enabled | Whether or not to associate a private hosted zone with the specified VPC for CloudTrail endpoint | string | `"false"` | no | +| cloudtrail\_endpoint\_security\_group\_ids | The ID of one or more security groups to associate with the network interface for CloudTrail endpoint | list | `[]` | no | +| cloudtrail\_endpoint\_subnet\_ids | The ID of one or more subnets in which to create a network interface for CloudTrail endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used. | list | `[]` | no | +| elasticloadbalancing\_endpoint\_private\_dns\_enabled | Whether or not to associate a private hosted zone with the specified VPC for Elastic Load Balancing endpoint | string | `"false"` | no | +| elasticloadbalancing\_endpoint\_security\_group\_ids | The ID of one or more security groups to associate with the network interface for Elastic Load Balancing endpoint | list | `[]` | no | +| elasticloadbalancing\_endpoint\_subnet\_ids | The ID of one or more subnets in which to create a network interface for Elastic Load Balancing endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used. | list | `[]` | no | +| logs\_endpoint\_private\_dns\_enabled | Whether or not to associate a private hosted zone with the specified VPC for CloudWatch Logs endpoint | string | `"false"` | no | +| logs\_endpoint\_security\_group\_ids | The ID of one or more security groups to associate with the network interface for CloudWatch Logs endpoint | list | `[]` | no | +| logs\_endpoint\_subnet\_ids | The ID of one or more subnets in which to create a network interface for CloudWatch Logs endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used. | list | `[]` | no | +| events\_endpoint\_private\_dns\_enabled | Whether or not to associate a private hosted zone with the specified VPC for CloudWatch Events endpoint | string | `"false"` | no | +| events\_endpoint\_security\_group\_ids | The ID of one or more security groups to associate with the network interface for CloudWatch Events endpoint | list | `[]` | no | +| events\_endpoint\_subnet\_ids | The ID of one or more subnets in which to create a network interface for CloudWatch Events endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used. | list | `[]` | no | +| monitoring\_endpoint\_private\_dns\_enabled | Whether or not to associate a private hosted zone with the specified VPC for CloudWatch Monitoring endpoint | string | `"false"` | no | +| monitoring\_endpoint\_security\_group\_ids | The ID of one or more security groups to associate with the network interface for CloudWatch Monitoring endpoint | list | `[]` | no | +| monitoring\_endpoint\_subnet\_ids | The ID of one or more subnets in which to create a network interface for CloudWatch Monitoring endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used. | list | `[]` | no | | elasticache\_acl\_tags | Additional tags for the elasticache subnets network ACL | map | `{}` | no | | elasticache\_dedicated\_network\_acl | Whether to use dedicated network ACL (not default) and custom rules for elasticache subnets | string | `"false"` | no | | elasticache\_inbound\_acl\_rules | Elasticache subnets inbound network ACL rules | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no | @@ -456,6 +476,24 @@ Sometimes it is handy to have public access to Redshift clusters (for example if | vpc\_endpoint\_ssmmessages\_dns\_entry | The DNS entries for the VPC Endpoint for SSMMESSAGES. | | vpc\_endpoint\_ssmmessages\_id | The ID of VPC endpoint for SSMMESSAGES | | vpc\_endpoint\_ssmmessages\_network\_interface\_ids | One or more network interfaces for the VPC Endpoint for SSMMESSAGES. | +| vpc\_endpoint\_sns\_dns\_entry | The DNS entries for the VPC Endpoint for SNS. | +| vpc\_endpoint\_sns\_id | The ID of VPC endpoint for SNS | +| vpc\_endpoint\_sns\_network\_interface\_ids | One or more network interfaces for the VPC Endpoint for SNS. | +| vpc\_endpoint\_cloudtrail\_dns\_entry | The DNS entries for the VPC Endpoint for CloudTrail. | +| vpc\_endpoint\_cloudtrail\_id | The ID of VPC endpoint for CloudTrail | +| vpc\_endpoint\_cloudtrail\_network\_interface\_ids | One or more network interfaces for the VPC Endpoint for CloudTrail. | +| vpc\_endpoint\_elasticloadbalancing\_dns\_entry | The DNS entries for the VPC Endpoint for Elastic Load Balancing. | +| vpc\_endpoint\_elasticloadbalancing\_id | The ID of VPC endpoint for Elastic Load Balancing | +| vpc\_endpoint\_elasticloadbalancing\_network\_interface\_ids | One or more network interfaces for the VPC Endpoint for Elastic Load Balancing. | +| vpc\_endpoint\_monitoring\_dns\_entry | The DNS entries for the VPC Endpoint for CloudWatch Monitoring. | +| vpc\_endpoint\_monitoring\_id | The ID of VPC endpoint for CloudWatch Monitoring | +| vpc\_endpoint\_monitoring\_network\_interface\_ids | One or more network interfaces for the VPC Endpoint for CloudWatch Monitoring. | +| vpc\_endpoint\_logs\_dns\_entry | The DNS entries for the VPC Endpoint for CloudWatch Logs. | +| vpc\_endpoint\_logs\_id | The ID of VPC endpoint for CloudWatch Logs | +| vpc\_endpoint\_logs\_network\_interface\_ids | One or more network interfaces for the VPC Endpoint for CloudWatch Logs. | +| vpc\_endpoint\_events\_dns\_entry | The DNS entries for the VPC Endpoint for CloudWatch Events. | +| vpc\_endpoint\_events\_id | The ID of VPC endpoint for CloudWatch Events | +| vpc\_endpoint\_events\_network\_interface\_ids | One or more network interfaces for the VPC Endpoint for CloudWatch Events. | | vpc\_id | The ID of the VPC | | vpc\_instance\_tenancy | Tenancy of instances spin up within VPC | | vpc\_main\_route\_table\_id | The ID of the main route table associated with this VPC | diff --git a/examples/issue-108-route-already-exists/main.tf b/examples/issue-108-route-already-exists/main.tf index 74f0af0c6..199b47a9f 100644 --- a/examples/issue-108-route-already-exists/main.tf +++ b/examples/issue-108-route-already-exists/main.tf @@ -19,4 +19,3 @@ module "vpc" { enable_s3_endpoint = true enable_dynamodb_endpoint = true } - diff --git a/main.tf b/main.tf index 6214e2d8e..e711af12b 100644 --- a/main.tf +++ b/main.tf @@ -898,6 +898,7 @@ resource "aws_vpc_endpoint_route_table_association" "public_dynamodb" { route_table_id = aws_route_table.public[0].id } + ####################### # VPC Endpoint for SQS ####################### @@ -1152,6 +1153,139 @@ resource "aws_vpc_endpoint" "ecs_telemetry" { private_dns_enabled = var.ecs_telemetry_endpoint_private_dns_enabled } + +####################### +# VPC Endpoint for SNS +####################### +data "aws_vpc_endpoint_service" "sns" { + count = var.create_vpc && var.enable_sns_endpoint ? 1 : 0 + + service = "sns" +} + +resource "aws_vpc_endpoint" "sns" { + count = var.create_vpc && var.enable_sns_endpoint ? 1 : 0 + + vpc_id = local.vpc_id + service_name = data.aws_vpc_endpoint_service.sns[0].service_name + vpc_endpoint_type = "Interface" + + security_group_ids = var.sns_endpoint_security_group_ids + subnet_ids = coalescelist(var.sns_endpoint_subnet_ids, aws_subnet.private.*.id) + private_dns_enabled = var.sns_endpoint_private_dns_enabled +} + + +####################### +# VPC Endpoint for CloudWatch Monitoring +####################### +data "aws_vpc_endpoint_service" "monitoring" { + count = var.create_vpc && var.enable_monitoring_endpoint ? 1 : 0 + + service = "monitoring" +} + +resource "aws_vpc_endpoint" "monitoring" { + count = var.create_vpc && var.enable_monitoring_endpoint ? 1 : 0 + + vpc_id = local.vpc_id + service_name = data.aws_vpc_endpoint_service.monitoring[0].service_name + vpc_endpoint_type = "Interface" + + security_group_ids = var.monitoring_endpoint_security_group_ids + subnet_ids = coalescelist(var.monitoring_endpoint_subnet_ids, aws_subnet.private.*.id) + private_dns_enabled = var.monitoring_endpoint_private_dns_enabled +} + + +####################### +# VPC Endpoint for CloudWatch Logs +####################### +data "aws_vpc_endpoint_service" "logs" { + count = var.create_vpc && var.enable_logs_endpoint ? 1 : 0 + + service = "logs" +} + +resource "aws_vpc_endpoint" "logs" { + count = var.create_vpc && var.enable_logs_endpoint ? 1 : 0 + + vpc_id = local.vpc_id + service_name = data.aws_vpc_endpoint_service.logs[0].service_name + vpc_endpoint_type = "Interface" + + security_group_ids = var.logs_endpoint_security_group_ids + subnet_ids = coalescelist(var.logs_endpoint_subnet_ids, aws_subnet.private.*.id) + private_dns_enabled = var.logs_endpoint_private_dns_enabled +} + + +####################### +# VPC Endpoint for CloudWatch Events +####################### +data "aws_vpc_endpoint_service" "events" { + count = var.create_vpc && var.enable_events_endpoint ? 1 : 0 + + service = "events" +} + +resource "aws_vpc_endpoint" "events" { + count = var.create_vpc && var.enable_events_endpoint ? 1 : 0 + + vpc_id = local.vpc_id + service_name = data.aws_vpc_endpoint_service.events[0].service_name + vpc_endpoint_type = "Interface" + + security_group_ids = var.events_endpoint_security_group_ids + subnet_ids = coalescelist(var.events_endpoint_subnet_ids, aws_subnet.private.*.id) + private_dns_enabled = var.events_endpoint_private_dns_enabled +} + + +####################### +# VPC Endpoint for Elastic Load Balancing +####################### +data "aws_vpc_endpoint_service" "elasticloadbalancing" { + count = var.create_vpc && var.enable_elasticloadbalancing_endpoint ? 1 : 0 + + service = "elasticloadbalancing" +} + +resource "aws_vpc_endpoint" "elasticloadbalancing" { + count = var.create_vpc && var.enable_elasticloadbalancing_endpoint ? 1 : 0 + + vpc_id = local.vpc_id + service_name = data.aws_vpc_endpoint_service.elasticloadbalancing[0].service_name + vpc_endpoint_type = "Interface" + + security_group_ids = var.elasticloadbalancing_endpoint_security_group_ids + subnet_ids = coalescelist(var.elasticloadbalancing_endpoint_subnet_ids, aws_subnet.private.*.id) + private_dns_enabled = var.elasticloadbalancing_endpoint_private_dns_enabled +} + + +####################### +# VPC Endpoint for CloudTrail +####################### +data "aws_vpc_endpoint_service" "cloudtrail" { + count = var.create_vpc && var.enable_cloudtrail_endpoint ? 1 : 0 + + service = "cloudtrail" +} + +resource "aws_vpc_endpoint" "cloudtrail" { + count = var.create_vpc && var.enable_cloudtrail_endpoint ? 1 : 0 + + vpc_id = local.vpc_id + service_name = data.aws_vpc_endpoint_service.cloudtrail[0].service_name + vpc_endpoint_type = "Interface" + + security_group_ids = var.cloudtrail_endpoint_security_group_ids + subnet_ids = coalescelist(var.cloudtrail_endpoint_subnet_ids, aws_subnet.private.*.id) + private_dns_enabled = var.cloudtrail_endpoint_private_dns_enabled +} + + ########################## # Route table association ########################## diff --git a/outputs.tf b/outputs.tf index 03626018d..71164fcd6 100644 --- a/outputs.tf +++ b/outputs.tf @@ -528,6 +528,96 @@ output "vpc_endpoint_ecs_telemetry_dns_entry" { value = "${flatten(aws_vpc_endpoint.ecs_telemetry.*.dns_entry)}" } +output "vpc_endpoint_sns_id" { + description = "The ID of VPC endpoint for SNS" + value = concat(aws_vpc_endpoint.sns.*.id, [""])[0] +} + +output "vpc_endpoint_sns_network_interface_ids" { + description = "One or more network interfaces for the VPC Endpoint for SNS." + value = flatten(aws_vpc_endpoint.sns.*.network_interface_ids) +} + +output "vpc_endpoint_sns_dns_entry" { + description = "The DNS entries for the VPC Endpoint for SNS." + value = flatten(aws_vpc_endpoint.sns.*.dns_entry) +} + +output "vpc_endpoint_monitoring_id" { + description = "The ID of VPC endpoint for CloudWatch Monitoring" + value = concat(aws_vpc_endpoint.monitoring.*.id, [""])[0] +} + +output "vpc_endpoint_monitoring_network_interface_ids" { + description = "One or more network interfaces for the VPC Endpoint for CloudWatch Monitoring." + value = flatten(aws_vpc_endpoint.monitoring.*.network_interface_ids) +} + +output "vpc_endpoint_monitoring_dns_entry" { + description = "The DNS entries for the VPC Endpoint for CloudWatch Monitoring." + value = flatten(aws_vpc_endpoint.monitoring.*.dns_entry) +} + +output "vpc_endpoint_logs_id" { + description = "The ID of VPC endpoint for CloudWatch Logs" + value = concat(aws_vpc_endpoint.logs.*.id, [""])[0] +} + +output "vpc_endpoint_logs_network_interface_ids" { + description = "One or more network interfaces for the VPC Endpoint for CloudWatch Logs." + value = flatten(aws_vpc_endpoint.logs.*.network_interface_ids) +} + +output "vpc_endpoint_logs_dns_entry" { + description = "The DNS entries for the VPC Endpoint for CloudWatch Logs." + value = flatten(aws_vpc_endpoint.logs.*.dns_entry) +} + +output "vpc_endpoint_events_id" { + description = "The ID of VPC endpoint for CloudWatch Events" + value = concat(aws_vpc_endpoint.events.*.id, [""])[0] +} + +output "vpc_endpoint_events_network_interface_ids" { + description = "One or more network interfaces for the VPC Endpoint for CloudWatch Events." + value = flatten(aws_vpc_endpoint.events.*.network_interface_ids) +} + +output "vpc_endpoint_events_dns_entry" { + description = "The DNS entries for the VPC Endpoint for CloudWatch Events." + value = flatten(aws_vpc_endpoint.events.*.dns_entry) +} + +output "vpc_endpoint_elasticloadbalancing_id" { + description = "The ID of VPC endpoint for Elastic Load Balancing" + value = concat(aws_vpc_endpoint.elasticloadbalancing.*.id, [""])[0] +} + +output "vpc_endpoint_elasticloadbalancing_network_interface_ids" { + description = "One or more network interfaces for the VPC Endpoint for Elastic Load Balancing." + value = flatten(aws_vpc_endpoint.elasticloadbalancing.*.network_interface_ids) +} + +output "vpc_endpoint_elasticloadbalancing_dns_entry" { + description = "The DNS entries for the VPC Endpoint for Elastic Load Balancing." + value = flatten(aws_vpc_endpoint.elasticloadbalancing.*.dns_entry) +} + +output "vpc_endpoint_cloudtrail_id" { + description = "The ID of VPC endpoint for CloudTrail" + value = concat(aws_vpc_endpoint.cloudtrail.*.id, [""])[0] +} + +output "vpc_endpoint_cloudtrail_network_interface_ids" { + description = "One or more network interfaces for the VPC Endpoint for CloudTrail." + value = flatten(aws_vpc_endpoint.cloudtrail.*.network_interface_ids) +} + +output "vpc_endpoint_cloudtrail_dns_entry" { + description = "The DNS entries for the VPC Endpoint for CloudTrail." + value = flatten(aws_vpc_endpoint.cloudtrail.*.dns_entry) +} + # Static values (arguments) output "azs" { description = "A list of availability zones specified as argument to this module" diff --git a/variables.tf b/variables.tf index de3106f28..e063fe2cb 100644 --- a/variables.tf +++ b/variables.tf @@ -502,6 +502,150 @@ variable "ecs_telemetry_endpoint_private_dns_enabled" { default = false } +variable "enable_sns_endpoint" { + description = "Should be true if you want to provision a SNS endpoint to the VPC" + type = bool + default = false +} + +variable "sns_endpoint_security_group_ids" { + description = "The ID of one or more security groups to associate with the network interface for SNS endpoint" + type = list(string) + default = [] +} + +variable "sns_endpoint_subnet_ids" { + description = "The ID of one or more subnets in which to create a network interface for SNS endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used." + type = list(string) + default = [] +} + +variable "sns_endpoint_private_dns_enabled" { + description = "Whether or not to associate a private hosted zone with the specified VPC for SNS endpoint" + type = bool + default = false +} + +variable "enable_monitoring_endpoint" { + description = "Should be true if you want to provision a CloudWatch Monitoring endpoint to the VPC" + type = bool + default = false +} + +variable "monitoring_endpoint_security_group_ids" { + description = "The ID of one or more security groups to associate with the network interface for CloudWatch Monitoring endpoint" + type = list(string) + default = [] +} + +variable "monitoring_endpoint_subnet_ids" { + description = "The ID of one or more subnets in which to create a network interface for CloudWatch Monitoring endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used." + type = list(string) + default = [] +} + +variable "monitoring_endpoint_private_dns_enabled" { + description = "Whether or not to associate a private hosted zone with the specified VPC for CloudWatch Monitoring endpoint" + type = bool + default = false +} + +variable "enable_elasticloadbalancing_endpoint" { + description = "Should be true if you want to provision a Elastic Load Balancing endpoint to the VPC" + type = bool + default = false +} + +variable "elasticloadbalancing_endpoint_security_group_ids" { + description = "The ID of one or more security groups to associate with the network interface for Elastic Load Balancing endpoint" + type = list(string) + default = [] +} + +variable "elasticloadbalancing_endpoint_subnet_ids" { + description = "The ID of one or more subnets in which to create a network interface for Elastic Load Balancing endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used." + type = list(string) + default = [] +} + +variable "elasticloadbalancing_endpoint_private_dns_enabled" { + description = "Whether or not to associate a private hosted zone with the specified VPC for Elastic Load Balancing endpoint" + type = bool + default = false +} + +variable "enable_events_endpoint" { + description = "Should be true if you want to provision a CloudWatch Events endpoint to the VPC" + type = bool + default = false +} + +variable "events_endpoint_security_group_ids" { + description = "The ID of one or more security groups to associate with the network interface for CloudWatch Events endpoint" + type = list(string) + default = [] +} + +variable "events_endpoint_subnet_ids" { + description = "The ID of one or more subnets in which to create a network interface for CloudWatch Events endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used." + type = list(string) + default = [] +} + +variable "events_endpoint_private_dns_enabled" { + description = "Whether or not to associate a private hosted zone with the specified VPC for CloudWatch Events endpoint" + type = bool + default = false +} + +variable "enable_logs_endpoint" { + description = "Should be true if you want to provision a CloudWatch Logs endpoint to the VPC" + type = bool + default = false +} + +variable "logs_endpoint_security_group_ids" { + description = "The ID of one or more security groups to associate with the network interface for CloudWatch Logs endpoint" + type = list(string) + default = [] +} + +variable "logs_endpoint_subnet_ids" { + description = "The ID of one or more subnets in which to create a network interface for CloudWatch Logs endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used." + type = list(string) + default = [] +} + +variable "logs_endpoint_private_dns_enabled" { + description = "Whether or not to associate a private hosted zone with the specified VPC for CloudWatch Logs endpoint" + type = bool + default = false +} + +variable "enable_cloudtrail_endpoint" { + description = "Should be true if you want to provision a CloudTrail endpoint to the VPC" + type = bool + default = false +} + +variable "cloudtrail_endpoint_security_group_ids" { + description = "The ID of one or more security groups to associate with the network interface for CloudTrail endpoint" + type = list(string) + default = [] +} + +variable "cloudtrail_endpoint_subnet_ids" { + description = "The ID of one or more subnets in which to create a network interface for CloudTrail endpoint. Only a single subnet within an AZ is supported. If omitted, private subnets will be used." + type = list(string) + default = [] +} + +variable "cloudtrail_endpoint_private_dns_enabled" { + description = "Whether or not to associate a private hosted zone with the specified VPC for CloudTrail endpoint" + type = bool + default = false +} + variable "map_public_ip_on_launch" { description = "Should be false if you do not want to auto-assign public IP on launch" type = bool