Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a parameter to avoid deploying the service-linked roles with CFN #104

Merged
merged 2 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion elastio-terraform-deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ module "elastio" {

# This input is optional. Here you can specify the version of the NAT provisioning stack.
# If you don't need it, just omit this input variable.
elastio_nat_provision_stack = "v4"
elastio_nat_provision_stack = "v5"
}
```
34 changes: 34 additions & 0 deletions elastio-terraform-deployment/module/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ locals {
iamResourceNamesSuffix = var.iam_resource_names_suffix
iamResourceNamesStatic = var.iam_resource_names_static
disableCustomerManagedIamPolicies = var.disable_customer_managed_iam_policies
disableServiceLinkedRolesCreation = var.service_linked_roles == "tf"
supportRoleExpirationDate = var.support_role_expiration_date
tenantRoleArn = "arn:aws:iam::176355207749:role/vkryvenko.development.elastio.us"
}
Expand Down Expand Up @@ -73,9 +74,42 @@ locals {
key => tostring(value)
if value != null
}

service_linked_roles_services = [
"ecs.amazonaws.com",
"batch.amazonaws.com",
"spot.amazonaws.com",
"spotfleet.amazonaws.com",
"ecs.application-autoscaling.amazonaws.com",
"autoscaling.amazonaws.com",
]
}

# We have to use the `terraform_data` resource for the service-linked roles
# because their creation needs to be idempotent and terraform shouldn't claim
# ownership of them. These roles may already exist in the account, and they
# may be used by other resources not managed by Elastio.
resource "terraform_data" "service_linked_roles" {
for_each = var.service_linked_roles == "tf" ? local.service_linked_roles_services : toset([])

input = each.value
triggers_replace = each.value

provisioner "local-exec" {
command = <<CMD
aws iam create-service-linked-role --aws-service-name $service_name || true
CMD

environment = {
service_name = self.input
}
}
}


resource "aws_cloudformation_stack" "elastio_account_level_stack" {
depends_on = [terraform_data.service_linked_roles]

name = "elastio-account-level-stack"
template_url = data.http.cloudformation_template.response_body
tags = {
Expand Down
33 changes: 32 additions & 1 deletion elastio-terraform-deployment/module/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ variable "elastio_cloud_connectors" {

variable "elastio_nat_provision_stack" {
description = <<DESCR
Specifies the version of Elastio NAT provision stack to deploy (e.g. `v4`).
Specifies the version of Elastio NAT provision stack to deploy (e.g. `v5`).

This is a Cloudformation stack that automatically provisions NAT Gateways in
your VPC when Elastio worker instances run to provide them with the outbound
Expand Down Expand Up @@ -149,6 +149,37 @@ variable "disable_customer_managed_iam_policies" {
default = null
}

variable "service_linked_roles" {
description = <<DESCR
By default the CFN stack creates the service-linked IAM roles needed by the stack.
Since these are global in your account, they can't be defined as regular resources
in the CFN, because these roles may already exist in your account and thus
the deployment would fail on a name conflict.

Instead, by default, they are deployed using an AWS::CloudFormation::CustomResource
which invokes an AWS Lambda function that creates the service-linked roles only if
they don't exist and doesn't fail if they do.

The default approach of creating the service-linked roles via the CFN requires
creating a lambda function in your environment that has IAM write permission of
`iam:CreateServiceLinkedRole`. If you can't afford creating such a lambda function
then set this parameter to `tf` and this terraform module will create the
service-linked roles without the need for a lambda function.

If you set this to `tf`, then make sure you have the AWS CLI installed and
configured with the necessary credentials on the machine where you run terraform.
DESCR

type = string
default = "cfn"
nullable = false

validation {
condition = contains(["cfn", "tf"], var.service_linked_roles)
error_message = "service_linked_roles must be one of 'cfn', 'tf'"
}
}

variable "support_role_expiration_date" {
description = <<DESCR
Specifies a date when the ElastioSupport role will be disabled. This role
Expand Down