Skip to content

Commit d56a38f

Browse files
committed
Extract nat provision stack
1 parent c94224d commit d56a38f

File tree

12 files changed

+319
-178
lines changed

12 files changed

+319
-178
lines changed
File renamed without changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
module "elastio_connectors" {
3+
source = "../../"
4+
5+
elastio_tenant = var.elastio_tenant
6+
elastio_pat = var.elastio_pat
7+
8+
elastio_cloud_connectors = [
9+
{
10+
region = "us-east-1"
11+
},
12+
{
13+
region = "us-east-2",
14+
}
15+
]
16+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
variable "elastio_pat" {
2+
description = "Personal Access Token generated by the Elastio Portal"
3+
sensitive = true
4+
type = string
5+
nullable = false
6+
}
7+
8+
variable "elastio_tenant" {
9+
description = "Name of your Elastio tenant. For example `mycompany.app.elastio.com`"
10+
type = string
11+
nullable = false
12+
}
13+
14+
variable "elastio_cloud_connectors" {
15+
description = <<DESCR
16+
List of regions where Cloud Connectors are to be deployed, VPC and subnet(s) to use,
17+
and other regional configurations (mostly for regulatory compliance).
18+
DESCR
19+
20+
type = list(object({
21+
region = string
22+
vpc_id = optional(string)
23+
subnet_ids = optional(list(string))
24+
25+
s3_access_logging = optional(object({
26+
target_bucket = string
27+
target_prefix = optional(string)
28+
29+
# Can be one of the following:
30+
# - SimplePrefix
31+
# - PartitionedPrefix:EventTime
32+
# - PartitionedPrefix:DeliveryTime
33+
target_object_key_format = optional(string)
34+
}))
35+
}))
36+
37+
nullable = false
38+
default = []
39+
}

connector/terraform/main.tf

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1+
locals {
2+
connectors = {
3+
for connector in var.elastio_cloud_connectors :
4+
connector.region => connector
5+
}
6+
}
17

28
module "account" {
39
source = "./modules/account"
410

5-
elastio_pat = var.elastio_pat
6-
elastio_tenant = var.elastio_tenant
7-
elastio_cloud_connectors = var.elastio_cloud_connectors
11+
elastio_pat = var.elastio_pat
12+
elastio_tenant = var.elastio_tenant
13+
14+
regional_configs = var.elastio_cloud_connectors
815
encrypt_with_cmk = var.encrypt_with_cmk
916
lambda_tracing = var.lambda_tracing
1017
global_managed_policies = var.global_managed_policies
@@ -19,27 +26,22 @@ module "account" {
1926
}
2027

2128
module "region" {
22-
source = "./modules/region"
29+
source = "./modules/region"
30+
for_each = local.connectors
2331

24-
depends_on = [module.account]
32+
elastio_pat = var.elastio_pat
33+
elastio_tenant = var.elastio_tenant
2534

26-
for_each = {
27-
for connector in var.elastio_cloud_connectors :
28-
connector.region => connector
29-
}
35+
region = each.value.region
36+
vpc_id = each.value.vpc_id
37+
subnet_ids = each.value.subnet_ids
38+
connector_account_stack = each.value.account.cloudformation_stack
39+
}
40+
41+
module "nat_provision" {
42+
source = "./modules/nat-provision"
43+
for_each = var.elastio_nat_provision_stack == null ? [] : local.connectors
3044

31-
region = each.value.region
32-
vpc_id = each.value.vpc_id
33-
subnet_ids = each.value.subnet_ids
34-
connector_account_stack_name = each.value.connector_account_stack_name
35-
36-
elastio_pat = var.elastio_pat
37-
elastio_tenant = var.elastio_tenant
38-
elastio_nat_provision_stack = var.elastio_nat_provision_stack
39-
encrypt_with_cmk = var.encrypt_with_cmk
40-
lambda_tracing = var.lambda_tracing
41-
global_managed_policies = var.global_managed_policies
42-
global_permission_boundary = var.global_permission_boundary
43-
iam_resource_names_prefix = var.iam_resource_names_prefix
44-
iam_resource_names_suffix = var.iam_resource_names_suffix
45+
version = var.elastio_nat_provision_stack
46+
connector_account_stack = each.value.account.cloudformation_stack
4547
}

connector/terraform/modules/account/main.tf

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ data "http" "cloudformation_template" {
2323
}
2424

2525
locals {
26-
global_acc_cfn_params = {
26+
global_stack_params = {
2727
encryptWithCmk = var.encrypt_with_cmk,
2828
lambdaTracing = var.lambda_tracing,
2929
globalManagedPolicies = (
@@ -41,40 +41,34 @@ locals {
4141
ecrPublicPrefix = var.ecr_public_prefix
4242
}
4343

44-
enriched_connectors = [
45-
for connector in var.elastio_cloud_connectors :
44+
enriched_regional_configs = [
45+
for config in var.regional_configs :
4646
merge(
47-
connector,
47+
config,
4848
{
4949
# Add the PascalCase version of the region name, because this is the
5050
# naming convention used in CFN parameters for regional settings.
5151
region_pascal = join(
5252
"",
53-
[for word in split("-", connector.region) : title(word)]
53+
[for word in split("-", config.region) : title(word)]
5454
)
5555
}
5656
)
5757
]
5858

59-
regional_acc_cfn_params = merge(
59+
regional_stack_params = merge(
6060
[
61-
for connector in local.enriched_connectors :
61+
for config in local.enriched_regional_configs :
6262
{
63-
"s3AccessLoggingTargetBucket${connector.region_pascal}" = connector.s3_access_logging.target_bucket,
64-
"s3AccessLoggingTargetPrefix${connector.region_pascal}" = connector.s3_access_logging.target_prefix,
65-
"s3AccessLoggingTargetObjectKeyFormat${connector.region_pascal}" = connector.s3_access_logging.target_object_key_format,
63+
"s3AccessLoggingTargetBucket${config.region_pascal}" = config.s3_access_logging.target_bucket,
64+
"s3AccessLoggingTargetPrefix${config.region_pascal}" = config.s3_access_logging.target_prefix,
65+
"s3AccessLoggingTargetObjectKeyFormat${config.region_pascal}" = config.s3_access_logging.target_object_key_format,
6666
}
67-
if connector.s3_access_logging != null
67+
if config.s3_access_logging != null
6868
]
6969
...
7070
)
7171

72-
account_level_stack_params = {
73-
for key, value in merge(local.global_acc_cfn_params, local.regional_acc_cfn_params) :
74-
key => tostring(value)
75-
if value != null
76-
}
77-
7872
service_linked_roles_services = [
7973
"ecs.amazonaws.com",
8074
"batch.amazonaws.com",
@@ -106,8 +100,7 @@ resource "terraform_data" "service_linked_roles" {
106100
}
107101
}
108102

109-
110-
resource "aws_cloudformation_stack" "elastio_account_level_stack" {
103+
resource "aws_cloudformation_stack" "this" {
111104
depends_on = [terraform_data.service_linked_roles]
112105

113106
name = "elastio-account-level-stack"
@@ -116,5 +109,9 @@ resource "aws_cloudformation_stack" "elastio_account_level_stack" {
116109
"elastio:resource" = "true"
117110
}
118111
capabilities = ["CAPABILITY_NAMED_IAM"]
119-
parameters = local.account_level_stack_params
112+
parameters = {
113+
for key, value in merge(local.global_stack_params, local.regional_stack_params) :
114+
key => tostring(value)
115+
if value != null
116+
}
120117
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
output "cloudformation_stack" {
2+
description = <<DESCR
3+
The deployed CloudFormation stack may be used as an input for other stacks
4+
like the `nat-provision` stack to let it inherit the configurations.
5+
DESCR
6+
7+
value = aws_cloudformation_stack.this
8+
}

connector/terraform/modules/account/variables.tf

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#########################
2+
## Required parameters ##
3+
#########################
4+
15
variable "elastio_pat" {
26
description = "Personal Access Token generated by the Elastio Portal"
37
sensitive = true
@@ -11,10 +15,13 @@ variable "elastio_tenant" {
1115
nullable = false
1216
}
1317

14-
variable "elastio_cloud_connectors" {
18+
#########################
19+
## Optional parameters ##
20+
#########################
21+
22+
variable "regional_configs" {
1523
description = <<DESCR
16-
List of regions where Cloud Connectors are to be deployed, and some regional
17-
configurations (mostly for regulatory compliance).
24+
Regional configurations for connectors (mostly for regulatory compliance).
1825
DESCR
1926

2027
type = list(object({
@@ -36,6 +43,26 @@ variable "elastio_cloud_connectors" {
3643
default = []
3744
}
3845

46+
variable "network_configuration" {
47+
description = <<DESCR
48+
Can be set to either `Auto` or `Manual`. If set to `Auto`, Elastio will
49+
automatically create a VPC and subnets in the specified regions for the
50+
scan clusters to run in.
51+
52+
If set to `Manual`, you must provide the `vpc_id` and `subnet_ids` in the
53+
`region` module with the network config for each region.
54+
DESCR
55+
56+
type = string
57+
default = "Manual"
58+
nullable = false
59+
60+
validation {
61+
condition = contains(["Auto", "Manual"], var.network_configuration)
62+
error_message = "network_configuration must be one of 'Auto', 'Manual'"
63+
}
64+
}
65+
3966
variable "encrypt_with_cmk" {
4067
description = <<DESCR
4168
Provision additional customer-managed KMS keys to encrypt
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
resource "aws_cloudformation_stack" "this" {
2+
name = "elastio-nat-provision-lambda"
3+
template_url = join(
4+
"/",
5+
[
6+
"https://elastio-prod-artifacts-us-east-2.s3.us-east-2.amazonaws.com",
7+
"contrib/elastio-nat-provision-lambda/${var.version}",
8+
"cloudformation-lambda.yaml"
9+
]
10+
)
11+
tags = {
12+
"elastio:resource" = "true"
13+
}
14+
capabilities = ["CAPABILITY_NAMED_IAM"]
15+
parameters = {
16+
for key, value in var.connector_account_stack.parameters :
17+
key => value
18+
if contains(
19+
[
20+
"encryptWithCmk",
21+
"lambdaTracing",
22+
"globalManagedPolicies",
23+
"globalPermissionBoundary",
24+
"iamResourceNamesPrefix",
25+
"iamResourceNamesSuffix",
26+
],
27+
key
28+
)
29+
}
30+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#########################
2+
## Required parameters ##
3+
#########################
4+
5+
variable "connector_account_stack" {
6+
description = <<DESCR
7+
The Elastio Connector Account stack metadata. This is used to inherit the
8+
configs by the `nat-provision` stack. The value for this parameter can be
9+
provided as the `cloudformation_stack` output of the `account` module, or
10+
you could use a `data "aws_cloudformation_stack"` data source to fetch the
11+
stack metadata and provide it here.
12+
DESCR
13+
14+
type = object({
15+
parameters = map(string)
16+
})
17+
18+
nullable = false
19+
}
20+
21+
#########################
22+
## Optional parameters ##
23+
#########################
24+
25+
variable "version" {
26+
description = <<DESCR
27+
Specifies the version of Elastio NAT provision stack to deploy (e.g. `v5`).
28+
29+
This is a Cloudformation stack that automatically provisions NAT Gateways in
30+
your VPC when Elastio worker instances run to provide them with the outbound
31+
Internet access when Elastio is deployed in private subnets.
32+
33+
If you don't need this stack (e.g. you already have NAT gateways in your VPC
34+
or you deploy into public subnets) you can omit this parameter. The default
35+
value of `null` means there won't be any NAT provision stack deployed.
36+
37+
The source code of this stack can be found here:
38+
https://github.com/elastio/contrib/tree/master/elastio-nat-provision-lambda
39+
DESCR
40+
41+
type = string
42+
nullable = true
43+
default = "v5"
44+
}

connector/terraform/modules/region/main.tf

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,6 @@ locals {
55
}
66
}
77

8-
resource "aws_cloudformation_stack" "elastio_nat_provision_stack" {
9-
count = var.elastio_nat_provision_stack == null ? 0 : 1
10-
11-
name = "elastio-nat-provision-lambda"
12-
template_url = join(
13-
"/",
14-
[
15-
"https://elastio-prod-artifacts-us-east-2.s3.us-east-2.amazonaws.com",
16-
"contrib/elastio-nat-provision-lambda/${var.elastio_nat_provision_stack}",
17-
"cloudformation-lambda.yaml"
18-
]
19-
)
20-
tags = {
21-
"elastio:resource" = "true"
22-
}
23-
capabilities = ["CAPABILITY_NAMED_IAM"]
24-
parameters = {
25-
for key, value in {
26-
EncryptWithCmk = var.encrypt_with_cmk
27-
LambdaTracing = var.lambda_tracing
28-
IamResourceNamesPrefix = var.iam_resource_names_prefix
29-
IamResourceNamesSuffix = var.iam_resource_names_suffix
30-
GlobalManagedPolicies = (
31-
var.global_managed_policies == null
32-
? null
33-
: join(",", var.global_managed_policies)
34-
),
35-
GlobalPermissionBoundary = var.global_permission_boundary,
36-
} :
37-
key => tostring(value)
38-
if value != null
39-
}
40-
}
41-
428
data "aws_caller_identity" "current" {}
439
data "aws_region" "current" {}
4410

@@ -55,7 +21,7 @@ resource "terraform_data" "elastio_cloud_connector" {
5521
input = local.connector_config
5622
triggers_replace = {
5723
connector = local.connector_config,
58-
account_stack = var.connector_account_stack_name,
24+
account_stack = var.connector_account_stack.name,
5925
}
6026

6127
provisioner "local-exec" {

0 commit comments

Comments
 (0)