Skip to content

Commit

Permalink
Adds support for attaching to a TGW selected by its name (#2)
Browse files Browse the repository at this point in the history
* Adds support for attaching to a TGW selected by its name

* Adjusts CI execution

* Corrects source path for test case

* Fixes error when TGW ID is passed explicitly
  • Loading branch information
danvaida authored Apr 1, 2020
1 parent 01949b5 commit 2844944
Show file tree
Hide file tree
Showing 14 changed files with 303 additions and 18 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/terraform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,10 @@ jobs:

- name: "make test"
run: |
make test ARGS="-var assumer_account_role_name=test"
make test ARGS="-var aws_account_id_hub=${TF_VAR_aws_account_id_hub} -var aws_account_id_satellite=[${TF_VAR_aws_account_id_satellite}]"
env:
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
TF_VAR_aws_account_id_hub: ${{ secrets.aws_account_id_hub }}
TF_VAR_aws_account_id_satellite: ${{ secrets.aws_account_id_satellite }}
30 changes: 30 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log

# Ignore any .tfvars files that are generated automatically for each Terraform run. Most
# .tfvars files are managed as part of configuration and so should be included in
# version control.
#
# example.tfvars

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include override files you do wish to add to version control using negated pattern
#
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*
*tfplan*
59 changes: 53 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ test: _pull-tf
echo "------------------------------------------------------------"; \
echo "# Terraform init"; \
echo "------------------------------------------------------------"; \
if docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \
if docker run $$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \
init \
-verify-plugins=true \
-lock=false \
Expand All @@ -90,25 +90,72 @@ test: _pull-tf
echo "OK"; \
else \
echo "Failed"; \
docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \
docker run $$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \
exit 1; \
fi; \
echo; \
echo "------------------------------------------------------------"; \
echo "# Terraform validate"; \
echo "------------------------------------------------------------"; \
if docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \
if docker run $$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \
validate \
$(ARGS) \
.; then \
echo "OK"; \
docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \
else \
echo "Failed"; \
docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \
docker run $$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \
exit 1; \
fi; \
echo; \
echo "------------------------------------------------------------"; \
echo "# Terraform plan"; \
echo "------------------------------------------------------------"; \
if docker run $$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \
plan \
$(ARGS) \
-out=tfplan \
; then \
echo "OK"; \
else \
echo "Failed"; \
docker run $$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \
exit 1; \
fi; \
echo; \
echo "------------------------------------------------------------"; \
echo "# Terraform apply & destroy"; \
echo "------------------------------------------------------------"; \
if docker run $$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \
apply \
-auto-approve \
tfplan \
; then \
echo "Apply OK"; \
if docker run $$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \
destroy \
-auto-approve \
$(ARGS) \
; then \
echo "Destroy OK"; \
docker run $$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ terraform.tfstate terraform.tfstate.backup || true; \
else \
echo "Destroy failed. You should check for dangling resources."; \
exit 1; \
fi; \
else \
echo "Apply failed"; \
if docker run -$$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \
destroy \
-auto-approve \
$(ARGS) \
; then \
echo "Destroy OK"; \
docker run -$$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ terraform.tfstate terraform.tfstate.backup || true; \
else \
echo "Destroy failed. You should check for dangling resources."; \
exit 1; \
fi; \
fi; \
)


Expand Down
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,14 @@ Check the `subnet_name_keyword_selector` variable if you want to change this.
|------|-------------|------|---------|:-----:|
| aws\_account\_id\_hub | AWS account number containing the TGW hub | `string` | n/a | yes |
| aws\_login\_profile | Name of the AWS login profile as seen under ~/.aws/config used for assuming cross-account roles | `any` | n/a | yes |
| ram\_resource\_association\_id | Identifier of the Resource Access Manager Resource Association | `string` | n/a | yes |
| role\_to\_assume\_hub | IAM role name to assume in the AWS account containing the TGW hub (eg. ASSUME-ROLE-HUB) | `string` | n/a | yes |
| aws\_account\_id\_satellite | AWS account number containing the TGW satellite | `string` | `""` | no |
| destination\_cidr\_block | CIDR to be routed | `string` | `""` | no |
| ram\_resource\_association\_id | Identifier of the Resource Access Manager Resource Association | `string` | `""` | no |
| role\_to\_assume\_satellite | IAM role name to assume in the AWS account containing the TGW satellite (eg. ASSUME-ROLE-SATELLITE) | `string` | `""` | no |
| satellite\_create | Boolean flag for toggling the handling of satellite resources | `bool` | `false` | no |
| subnet\_name\_keyword\_selector | Keyword matching the name of the subnet(s) for which the routing will be added (i.e. private) | `string` | `"private"` | no |
| transit\_gateway\_hub\_name | Name of the Transit Gateway to attach to | `string` | `""` | no |
| transit\_gateway\_id | Identifier of the Transit Gateway | `string` | `""` | no |
| transit\_gateway\_route\_table\_id | Identifier of the Transit Gateway Route Table | `string` | `""` | no |
| vpc\_name\_to\_attach | Name of the satellite VPC to be attached to the TGW | `string` | `""` | no |
Expand All @@ -75,14 +76,17 @@ Check the `subnet_name_keyword_selector` variable if you want to change this.

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

## To do

- Collect TGW ID directly rather than using a RAM data source
([currently not supported][7])
- Add support for VPN attachments
- Add support for passing IDs of subnets while fetching routing table IDs

[1]: https://en.wikipedia.org/wiki/Star_network
[2]: https://github.com/Flaconi/terraform-aws-transit-gateway-hub
[3]: https://github.com/Flaconi/terraform-aws-transit-gateway-hub/tree/master/examples
[4]: https://docs.aws.amazon.com/cli/latest/reference/sts/assume-role.html#examples
[5]: https://www.terraform.io/docs/configuration/modules.html#passing-providers-explicitly
[6]: https://www.terraform.io/docs/providers/aws/index.html#authentication

## To do

- Add support for passing the IDs of the subnets as an input variable
- Add support for VPN attachments
[7]: https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-transit-gateways.html#options
38 changes: 38 additions & 0 deletions data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,41 @@ data "aws_route_table" "this" {

subnet_id = sort(data.aws_subnet_ids.this[0].ids)[count.index]
}

data "aws_ec2_transit_gateway" "this" {
provider = aws.hub
count = local.create && var.transit_gateway_hub_name != "" ? 1 : 0

filter {
name = "state"
values = ["available"]
}

filter {
name = "owner-id"
values = [var.aws_account_id_hub]
}

filter {
name = "transit-gateway-id"
values = [data.aws_ram_resource_share.this[0].tags.transit-gateway-id]
}
}

data "aws_ec2_transit_gateway_route_table" "this" {
provider = aws.hub
count = local.create && var.transit_gateway_hub_name != "" ? 1 : 0

filter {
name = "transit-gateway-id"
values = [data.aws_ec2_transit_gateway.this[0].id]
}
}

data "aws_ram_resource_share" "this" {
provider = aws.hub
count = local.create && var.transit_gateway_hub_name != "" ? 1 : 0

name = var.transit_gateway_hub_name
resource_owner = "SELF"
}
28 changes: 28 additions & 0 deletions examples/satellite/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Standalone invocation of the Transit Gateway satellite module

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Providers

No provider.

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:-----:|
| aws\_account\_id\_hub | AWS account number containing the TGW hub | `string` | n/a | yes |
| aws\_account\_id\_satellite | List of AWS account numbers representing the satellites of the TGW | `list` | n/a | yes |
| aws\_login\_profile | Name of the AWS login profile as seen under ~/.aws/config used for assuming cross-account roles | `any` | n/a | yes |
| role\_to\_assume\_hub | IAM role name to assume in the AWS account containing the TGW hub (eg. ASSUME-ROLE-HUB) | `string` | n/a | yes |
| role\_to\_assume\_satellite | IAM role name to assume in the AWS account containing the TGW satellite (eg. ASSUME-ROLE-SATELLITE) | `string` | n/a | yes |
| destination\_cidr\_block | CIDR to be routed | `string` | `""` | no |
| satellite\_create | Boolean flag for toggling the handling of satellite resources | `bool` | `false` | no |
| subnet\_name\_keyword\_selector | Keyword matching the name of the subnet(s) for which the routing will be added (i.e. private) | `string` | `"private"` | no |
| transit\_gateway\_hub\_name | Name of the Transit Gateway to attach to | `string` | `""` | no |
| transit\_gateway\_id | Identifier of the Transit Gateway | `string` | `""` | no |
| vpc\_name\_to\_attach | Name of the satellite VPC to be attached to the TGW | `string` | `""` | no |

## Outputs

No output.

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
6 changes: 6 additions & 0 deletions examples/satellite/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Workaround for this error when passing undeclared vars using CI/CD
# https://github.com/hashicorp/terraform/issues/22004
# TODO: refactor it after issue is resolved
locals {
aws_account_id_satellite = var.aws_account_id_satellite[0]
}
26 changes: 26 additions & 0 deletions examples/satellite/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# The Transit Gateway (hub) has already been created in AWS, as a fixture for
# this test case due to not being able to use 'depends_on' on Terraform modules
module "tgw-satellite" {
source = "../../"

providers = {
aws.satellite = aws.satellite
aws.hub = aws.hub
}

aws_login_profile = var.aws_login_profile
satellite_create = var.satellite_create

aws_account_id_hub = var.aws_account_id_hub
aws_account_id_satellite = local.aws_account_id_satellite

role_to_assume_hub = var.role_to_assume_hub
role_to_assume_satellite = var.role_to_assume_satellite

vpc_name_to_attach = var.vpc_name_to_attach
destination_cidr_block = var.destination_cidr_block

subnet_name_keyword_selector = var.subnet_name_keyword_selector

transit_gateway_hub_name = var.transit_gateway_hub_name
}
19 changes: 19 additions & 0 deletions examples/satellite/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
provider "aws" {
alias = "satellite"
region = "eu-central-1"
profile = var.aws_login_profile
assume_role {
role_arn = "arn:aws:iam::${local.aws_account_id_satellite}:role/${var.role_to_assume_satellite}"
session_name = "tf-tgw-module-satellite"
}
}

provider "aws" {
alias = "hub"
region = "eu-central-1"
profile = var.aws_login_profile
assume_role {
role_arn = "arn:aws:iam::${var.aws_account_id_hub}:role/${var.role_to_assume_hub}"
session_name = "tf-tgw-module-satellite"
}
}
12 changes: 12 additions & 0 deletions examples/satellite/variables.auto.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
satellite_create = true

aws_login_profile = "login"

role_to_assume_hub = "ASSUME-ENG-CI"
role_to_assume_satellite = "ASSUME-ENG-CI"

vpc_name_to_attach = "default"
destination_cidr_block = "1.1.1.1/32"

subnet_name_keyword_selector = "private"
transit_gateway_hub_name = "test-tgw-fixture"
58 changes: 58 additions & 0 deletions examples/satellite/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
variable "satellite_create" {
description = "Boolean flag for toggling the handling of satellite resources"
default = false
type = bool
}

variable "aws_login_profile" {
description = "Name of the AWS login profile as seen under ~/.aws/config used for assuming cross-account roles"
}

variable "aws_account_id_hub" {
description = "AWS account number containing the TGW hub"
type = string
}

variable "aws_account_id_satellite" {
description = "List of AWS account numbers representing the satellites of the TGW"
type = list
}

variable "role_to_assume_hub" {
description = "IAM role name to assume in the AWS account containing the TGW hub (eg. ASSUME-ROLE-HUB)"
type = string
}

variable "role_to_assume_satellite" {
description = "IAM role name to assume in the AWS account containing the TGW satellite (eg. ASSUME-ROLE-SATELLITE)"
type = string
}

variable "vpc_name_to_attach" {
description = "Name of the satellite VPC to be attached to the TGW"
type = string
default = ""
}

variable "destination_cidr_block" {
description = "CIDR to be routed"
default = ""
}

variable "subnet_name_keyword_selector" {
description = "Keyword matching the name of the subnet(s) for which the routing will be added (i.e. private)"
type = string
default = "private"
}

variable "transit_gateway_hub_name" {
description = "Name of the Transit Gateway to attach to"
type = string
default = ""
}

variable "transit_gateway_id" {
description = "Identifier of the Transit Gateway"
type = string
default = ""
}
4 changes: 4 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
locals {
create = var.satellite_create

transit_gateway_id = var.transit_gateway_id == "" ? data.aws_ec2_transit_gateway.this[0].id : var.transit_gateway_id

transit_gateway_route_table_id = var.transit_gateway_route_table_id == "" ? data.aws_ec2_transit_gateway_route_table.this[0].id : var.transit_gateway_route_table_id
}
Loading

0 comments on commit 2844944

Please sign in to comment.