Skip to content

Commit

Permalink
Merge pull request #60 from pablo19sc/main
Browse files Browse the repository at this point in the history
Adding AWS RAM share support (VPC Lattice service networks and services)
  • Loading branch information
pablo19sc authored Jul 23, 2024
2 parents 5e8245e + adc2e3b commit 6f4c2f6
Show file tree
Hide file tree
Showing 19 changed files with 273 additions and 3 deletions.
15 changes: 15 additions & 0 deletions .header.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ service_network = {
}
```

You can share VPC Lattice service networks using AWS RAM with this module. Check the section [Sharing VPC Lattice resources](#sharing-vpc-lattice-resources) for more information.

### VPC associations (var.vpc_associations)

When you associate a VPC with a service network, it enables all the targets within that VPC to be clients and communicate with other services associated to that same service network. You can make use of Security Groups to control the access of the VPC association, allowing some traffic segmentation before the traffic arrives to the Service Network.
Expand Down Expand Up @@ -299,3 +301,16 @@ services = {
}
}
```

You can share VPC Lattice services using AWS RAM with this module. Check the section [Sharing VPC Lattice resources](#sharing-vpc-lattice-resources) for more information.

## Sharing VPC Lattice resources

With [AWS Resource Access Manager](https://aws.amazon.com/ram/) (RAM), you can share VPC Lattice service networks and services. With this module, you can use the variable `var.ram_share` to share VPC Lattice resources. The variable supports the following attributes:

- `resources_share_arn` = (Optional|string) ARN of an **existing** RAM Resource Share to use to associate principals and VPC Lattice resources. **This attribute and `resource_share_name` cannot be set at the same time.**
- `resources_share_name` = (Optional|string) Name of the RAM Resource Share resource. This attribute creates a **new** resource using the specified name. **This attribute and `resources_share_arn` cannot be set at the same time.**
- `allow_external_principals` = (Optional|boolean) Indicates whether principals outside your organization can be associated with a resource share. **This attribute is allowed only when `resources_share_name` is provided.**
- `principals` = (Optional|list(string)) List of AWS principals to associated the resources with. Possible values are an AWS account ID, an AWS Organizations Organization ARN, or an AWS Organizations Organization Unit ARN.
- `share_service_network` = (Optional|boolean) Indicates whether a created VPC Lattice service network should be associated or not. Defaults to `true`.
- `share_services` = (Optional|list(string)) List of created VPC Lattice services to share. You should use the services' keys defined in `var.services`.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ service_network = {
}
```

You can share VPC Lattice service networks using AWS RAM with this module. Check the section [Sharing VPC Lattice resources](#sharing-vpc-lattice-resources) for more information.

### VPC associations (var.vpc\_associations)

When you associate a VPC with a service network, it enables all the targets within that VPC to be clients and communicate with other services associated to that same service network. You can make use of Security Groups to control the access of the VPC association, allowing some traffic segmentation before the traffic arrives to the Service Network.
Expand Down Expand Up @@ -301,6 +303,19 @@ services = {
}
```

You can share VPC Lattice services using AWS RAM with this module. Check the section [Sharing VPC Lattice resources](#sharing-vpc-lattice-resources) for more information.

## Sharing VPC Lattice resources

With [AWS Resource Access Manager](https://aws.amazon.com/ram/) (RAM), you can share VPC Lattice service networks and services. With this module, you can use the variable `var.ram_share` to share VPC Lattice resources. The variable supports the following attributes:

- `resources_share_arn` = (Optional|string) ARN of an **existing** RAM Resource Share to use to associate principals and VPC Lattice resources. **This attribute and `resource_share_name` cannot be set at the same time.**
- `resources_share_name` = (Optional|string) Name of the RAM Resource Share resource. This attribute creates a **new** resource using the specified name. **This attribute and `resources_share_arn` cannot be set at the same time.**
- `allow_external_principals` = (Optional|boolean) Indicates whether principals outside your organization can be associated with a resource share. **This attribute is allowed only when `resources_share_name` is provided.**
- `principals` = (Optional|list(string)) List of AWS principals to associated the resources with. Possible values are an AWS account ID, an AWS Organizations Organization ARN, or an AWS Organizations Organization Unit ARN.
- `share_service_network` = (Optional|boolean) Indicates whether a created VPC Lattice service network should be associated or not. Defaults to `true`.
- `share_services` = (Optional|list(string)) List of created VPC Lattice services to share. You should use the services' keys defined in `var.services`.

## Requirements

| Name | Version |
Expand All @@ -326,6 +341,10 @@ services = {

| Name | Type |
|------|------|
| [aws_ram_principal_association.ram_principal_association](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_principal_association) | resource |
| [aws_ram_resource_association.ram_service_network_association](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_resource_association) | resource |
| [aws_ram_resource_association.ram_services_association](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_resource_association) | resource |
| [aws_ram_resource_share.ram_resource_share](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_resource_share) | resource |
| [aws_vpclattice_auth_policy.service_auth_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpclattice_auth_policy) | resource |
| [aws_vpclattice_auth_policy.service_network_auth_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpclattice_auth_policy) | resource |
| [aws_vpclattice_service.lattice_service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpclattice_service) | resource |
Expand All @@ -340,6 +359,7 @@ services = {

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_ram_share"></a> [ram\_share](#input\_ram\_share) | Configuration of the resources to share using AWS Resource Access Manager (RAM). VPC Lattice service networks and services can be shared using RAM.<br>More information about the format of this variable can be found in the "Usage - AWS RAM share" section of the README. | `any` | `{}` | no |
| <a name="input_service_network"></a> [service\_network](#input\_service\_network) | Amazon VPC Lattice Service Network information. You can either create a new Service Network or reference a current one (to associate Services or VPCs). Setting the `name` attribute will create a **new** service network, while using the attribute `identifier` will reference an **existing** service network.<br>More information about the format of this variable can be found in the "Usage - Service Network" section of the README. | `any` | `{}` | no |
| <a name="input_services"></a> [services](#input\_services) | Definition of the VPC Lattice Services to create. You can use this module to either create only Lattice services (not associated with any service network), or associated with a service network (if you create one or provide an identifier). You can define 1 or more Service using this module.<br>More information about the format of this variable can be found in the "Usage - Services" section of the README. | `any` | `{}` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to apply to all the resources created in this module. | `map(string)` | `{}` | no |
Expand All @@ -351,6 +371,7 @@ services = {
| Name | Description |
|------|-------------|
| <a name="output_listeners_by_service"></a> [listeners\_by\_service](#output\_listeners\_by\_service) | VPC Lattice Listener and Rules. Per Lattice Service, each Listener is composed by the following attributes:<br>- `attributes` = Full output of **aws\_vpclattice\_listener**.<br>- `rules` = Full output of **aws\_vpclattice\_listener\_rule**. |
| <a name="output_ram_resource_share"></a> [ram\_resource\_share](#output\_ram\_resource\_share) | AWS Resource Access Manager resource share. Full output of **aws\_ram\_resource\_share**. |
| <a name="output_service_network"></a> [service\_network](#output\_service\_network) | VPC Lattice resource attributes. Full output of **aws\_vpclattice\_service\_network**. |
| <a name="output_services"></a> [services](#output\_services) | VPC Lattice Services. The output is composed by the following attributes (per Service created):<br>- `attributes` = Full output of **aws\_vpclattice\_service**.<br>- `service_network_association` = Full output of **aws\_vpclattice\_service\_network\_service\_association**. |
| <a name="output_target_groups"></a> [target\_groups](#output\_target\_groups) | VPC Lattice Target Groups. Full output of **aws\_vpclattice\_target\_group**. |
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.1.0
v0.2.0
15 changes: 15 additions & 0 deletions data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ locals {
# Checking if Service Network auth policy should be created
sn_auth_policy = (try(var.service_network.auth_type, "NONE") == "AWS_IAM") && (contains(keys(var.service_network), "auth_policy"))


# ---------- VPC Lattice Service variables ---------
# Service Association - if Service Network is created or passed
create_service_association = local.create_service_network || local.sn_identifier_provided
Expand All @@ -23,6 +24,20 @@ locals {
try({ for k, v in aws_vpclattice_target_group.lambda_lattice_target_group : k => v.id }, {}),
try({ for k, v in aws_vpclattice_target_group.lattice_target_group : k => v.id }, {}),
)

# ---------- AWS RAM SHARE ----------
# Determining if a RAM resource share has to be created
create_ram_resource_share = contains(keys(var.ram_share), "resource_share_name")
# Determining if any RAM share configuration has to be created
config_ram_share = length(keys(var.ram_share)) > 0
# Getting RAM resource share ARN
resource_share_arn = local.create_ram_resource_share ? aws_ram_resource_share.ram_resource_share[0].arn : try(var.ram_share.resource_share_arn, null)
# Determining if the service network needs to be shared
share_service_network = local.config_ram_share ? local.create_service_network && try(var.ram_share.share_service_network, true) : false
# Default of var.ram_share.share_services - if not defined, all the created services will be included
share_services = try(var.ram_share.share_services, keys(var.services))
# Move var.ram_share.principals from list(string) to map(string)
principals_map = { for index, principal in try(var.ram_share.principals, []) : index => principal }
}

# Sanitizes tags for aws provider
Expand Down
11 changes: 11 additions & 0 deletions examples/ram_share/.header.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Amazon VPC Lattice - Example: AWS RAM share

This example shows how you can use the VPC Lattice module to share service networks and services using [AWS Resource Access Manager](https://aws.amazon.com/ram/) RAM. The example creates the following:

* 1 VPC Lattice service network.
* 3 VPC Lattice services - basic configuration (without listeners or targets).
* 2 RAM shares. One is sharing the service network, and the other one is sharing 2 out of the 3 VPC Lattice services created.

**NOTE**: Given we automate these examples before merging new PRs, there's an [AWS Systems Manager parameter](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) data source configured to obtain an Account ID from a parameter configured in the AWS Account we use for the automated tests. Take that into account when doing your own tests, and please remember to keep this configuration when doing any PR to this repository.

In the `outputs.tf` file, you can see an example on how to obtain the information about the RAM share created (if applicable).
50 changes: 50 additions & 0 deletions examples/ram_share/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!-- BEGIN_TF_DOCS -->
# Amazon VPC Lattice - Example: AWS RAM share

This example shows how you can use the VPC Lattice module to share service networks and services using [AWS Resource Access Manager](https://aws.amazon.com/ram/) RAM. The example creates the following:

* 1 VPC Lattice service network.
* 3 VPC Lattice services - basic configuration (without listeners or targets).
* 2 RAM shares. One is sharing the service network, and the other one is sharing 2 out of the 3 VPC Lattice services created.

**NOTE**: Given we automate these examples before merging new PRs, there's an [AWS Systems Manager parameter](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) data source configured to obtain an Account ID from a parameter configured in the AWS Account we use for the automated tests. Take that into account when doing your own tests, and please remember to keep this configuration when doing any PR to this repository.

In the `outputs.tf` file, you can see an example on how to obtain the information about the RAM share created (if applicable).

## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.66.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.66.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_vpclattice_service_network_share"></a> [vpclattice\_service\_network\_share](#module\_vpclattice\_service\_network\_share) | ../.. | n/a |
| <a name="module_vpclattice_services_share"></a> [vpclattice\_services\_share](#module\_vpclattice\_services\_share) | ../.. | n/a |

## Resources

| Name | Type |
|------|------|
| [aws_ram_resource_share.vpclattice_resource_share](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_resource_share) | resource |
| [aws_ssm_parameter.account_id](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_aws_region"></a> [aws\_region](#input\_aws\_region) | AWS Region to use. | `string` | `"eu-west-1"` | no |

## Outputs

No outputs.
<!-- END_TF_DOCS -->
53 changes: 53 additions & 0 deletions examples/ram_share/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# --- examples/ram_share/main.tf ---

# Obtaining the AWS Account ID to share the resources with.
# If you are testing outside the module automation, either change this value with an AWS Account you own, or create a Parameter with this value
data "aws_ssm_parameter" "account_id" {
name = "account_id_share"
}

module "vpclattice_service_network_share" {
source = "../.."

service_network = {
name = "service-network"
auth_type = "NONE"
}

ram_share = {
resource_share_name = "service-network-resource-share"
allow_external_principals = true
principals = [data.aws_ssm_parameter.account_id.value]
}
}

module "vpclattice_services_share" {
source = "../.."

services = {
service1 = {
name = "service1"
auth_type = "NONE"
}
service2 = {
name = "service2"
auth_type = "NONE"
}
service3 = {
name = "service3"
auth_type = "NONE"
}
}

ram_share = {
resource_share_arn = aws_ram_resource_share.vpclattice_resource_share.arn
principals = [data.aws_ssm_parameter.account_id.value]
share_services = ["service1", "service2"]
}
}

resource "aws_ram_resource_share" "vpclattice_resource_share" {
name = "services-resource-share"
allow_external_principals = true
}

1 change: 1 addition & 0 deletions examples/ram_share/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# --- examples/ram_share/outputs.tf ---
16 changes: 16 additions & 0 deletions examples/ram_share/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# --- examples/ram_share/providers.tf ---

terraform {
required_version = ">= 1.3.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.66.0"
}
}
}

# Provider definition
provider "aws" {
region = var.aws_region
}
7 changes: 7 additions & 0 deletions examples/ram_share/variablest.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# --- examples/ram_share/variables.tf ---

variable "aws_region" {
type = string
description = "AWS Region to use."
default = "eu-west-1"
}
2 changes: 1 addition & 1 deletion examples/target_groups/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ resource "aws_lambda_function" "lambda" {

data "archive_file" "python_lambda_package" {
type = "zip"
source_file = "./function.py"
source_file = "${path.module}/function.py"
output_path = "lambda_function.zip"
}

Expand Down
Binary file added lambda_function.zip
Binary file not shown.
38 changes: 38 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,42 @@ module "listeners" {
service_identifier = try(each.value.identifier, aws_vpclattice_service.lattice_service[each.key].id)
target_groups = local.target_group_ids
tags = module.tags.tags_aws
}

# ---------- AWS RESOURCE ACCESS MANAGER ----------
# Create AWS RAM Resource Share (if name provided)
resource "aws_ram_resource_share" "ram_resource_share" {
count = local.create_ram_resource_share ? 1 : 0

name = var.ram_share.resource_share_name
allow_external_principals = try(var.ram_share.allow_external_principals, false)

tags = module.tags.tags_aws
}

# AWS RAM principal association
resource "aws_ram_principal_association" "ram_principal_association" {
for_each = {
for k, v in local.principals_map : k => v
if local.config_ram_share
}

principal = each.value
resource_share_arn = local.resource_share_arn
}

# AWS RAM resource association - VPC Lattice service network
resource "aws_ram_resource_association" "ram_service_network_association" {
count = local.share_service_network ? 1 : 0

resource_arn = aws_vpclattice_service_network.lattice_service_network[0].arn
resource_share_arn = local.resource_share_arn
}

# AWS RAM resource association - VPC Lattice services
resource "aws_ram_resource_association" "ram_services_association" {
count = local.config_ram_share ? length(local.share_services) : 0

resource_arn = aws_vpclattice_service.lattice_service[local.share_services[count.index]].arn
resource_share_arn = local.resource_share_arn
}
7 changes: 7 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,11 @@ output "listeners_by_service" {
- `attributes` = Full output of **aws_vpclattice_listener**.
- `rules` = Full output of **aws_vpclattice_listener_rule**.
EOF
}

output "ram_resource_share" {
value = try(aws_ram_resource_share.ram_resource_share[0], null)
description = <<-EOF
AWS Resource Access Manager resource share. Full output of **aws_ram_resource_share**.
EOF
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 14 additions & 0 deletions tests/06_ram_share.tftest.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

run "plan_ram_share" {
command = plan
module {
source = "./examples/ram_share"
}
}

run "apply_ram_share" {
command = apply
module {
source = "./examples/ram_share"
}
}
Loading

0 comments on commit 6f4c2f6

Please sign in to comment.