From 932cca0a4ace0669e99ebff212a19f493812d967 Mon Sep 17 00:00:00 2001 From: Ondrej Smola Date: Mon, 17 Mar 2025 13:13:03 +0100 Subject: [PATCH 1/9] wip --- iam.tf | 5 +++++ main.tf | 23 ++++++++++++++++++++--- user-data.sh.tpl | 13 +++++++++++-- variables.tf | 22 +++++++++++++++++++++- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/iam.tf b/iam.tf index e51b3c8..81a1d55 100644 --- a/iam.tf +++ b/iam.tf @@ -1,3 +1,5 @@ + + locals { managed_policies = [ "arn:${data.aws_partition.current.partition}:iam::aws:policy/IAMFullAccess", @@ -15,6 +17,8 @@ data "aws_partition" "current" {} resource "aws_iam_role" "this" { name = "${local.name}-instance" description = "Role assumed by EC2 instance(s) running altinity/cloud-connect" + + permissions_boundary = var.permissions_boundary assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ @@ -33,6 +37,7 @@ resource "aws_iam_role_policy" "this" { name = "${aws_iam_role.this.name}-policy" role = aws_iam_role.this.id + policy = jsonencode({ Version = "2012-10-17", Statement = [ diff --git a/main.tf b/main.tf index 84017a6..fdddbd6 100644 --- a/main.tf +++ b/main.tf @@ -43,7 +43,17 @@ resource "aws_ssm_parameter" "this" { name = "${local.name}-secret" type = "String" value = var.pem - tier = "Advanced" # value is over 4kb + tier = "Intelligent-Tiering" + tags = local.tags +} + +resource "aws_ssm_parameter" "ca_crt" { + count = var.ca_crt != "" ? 1 : 0 + name = "${local.name}-ca-pem" + type = "String" + value = var.ca_crt + tier = "Intelligent-Tiering" + tags = local.tags } data "aws_ssm_parameter" "this" { @@ -77,11 +87,14 @@ resource "aws_launch_template" "this" { image = var.image, ssm_parameter_name = var.pem_ssm_parameter_name != "" ? data.aws_ssm_parameter.this[0].name : aws_ssm_parameter.this[0].name url = var.url + ca_crt_ssm_parameter_name = var.ca_crt != "" ? aws_ssm_parameter.ca_crt[0].name : "" + host_aliases = var.host_aliases asg_name = local.name asg_hook_name = "launch" }) ) + tag_specifications { resource_type = "instance" tags = merge(local.tags, { @@ -98,15 +111,19 @@ resource "aws_autoscaling_group" "this" { max_size = 3 launch_template { id = aws_launch_template.this.id - version = "$Latest" + version = aws_launch_template.this.latest_version } initial_lifecycle_hook { name = "launch" lifecycle_transition = "autoscaling:EC2_INSTANCE_LAUNCHING" - heartbeat_timeout = "420" // 8m + heartbeat_timeout = "420" default_result = "ABANDON" } + instance_refresh { + strategy = "Rolling" + } + wait_for_capacity_timeout = "7m" vpc_zone_identifier = length(var.subnets) > 0 ? var.subnets : ( var.use_default_subnets ? data.aws_subnets.default[0].ids : aws_subnet.this.*.id diff --git a/user-data.sh.tpl b/user-data.sh.tpl index 75c2800..6caaa6e 100644 --- a/user-data.sh.tpl +++ b/user-data.sh.tpl @@ -19,9 +19,18 @@ on_exit() { trap on_exit EXIT mkdir -p /etc/altinitycloud + aws ssm get-parameter --name "${ssm_parameter_name}" --with-decryption --query "Parameter.Value" --output text > /etc/altinitycloud/cloud-connect.pem -docker run -d --name=altinitycloud-connect --restart=always -v /etc/altinitycloud:/etc/altinitycloud:rw --network=host "${image}" \ - --url=${url} -i /etc/altinitycloud/cloud-connect.pem --capability aws + +%{ if ca_crt_ssm_parameter_name != "" } +aws ssm get-parameter --name "${ca_crt_ssm_parameter_name}" --with-decryption --query "Parameter.Value" --output text > /etc/altinitycloud/ca.pem +%{ endif } + +docker run -d --name=altinitycloud-connect --restart=always -v /etc/altinitycloud:/etc/altinitycloud:rw --network=host \ + %{ for host, alias in host_aliases } --add-host="${host}:${alias}" %{ endfor } "${image}" \ + --url=${url} -i /etc/altinitycloud/cloud-connect.pem %{ if ca_crt_ssm_parameter_name != "" } --ca-crt=/etc/altinitycloud/ca.pem %{ endif } \ + --capability aws --dual-tcp-udp + aws autoscaling complete-lifecycle-action --lifecycle-action-result CONTINUE --instance-id "$instance" \ --lifecycle-hook-name ${asg_hook_name} --auto-scaling-group-name ${asg_name} diff --git a/variables.tf b/variables.tf index 469acbc..60bd1e6 100644 --- a/variables.tf +++ b/variables.tf @@ -20,6 +20,20 @@ EOT default = "" } +variable "ca_crt" { + type = string + description = < Date: Tue, 18 Mar 2025 15:43:39 +0100 Subject: [PATCH 2/9] wip --- main.tf | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/main.tf b/main.tf index fdddbd6..0796261 100644 --- a/main.tf +++ b/main.tf @@ -128,4 +128,14 @@ resource "aws_autoscaling_group" "this" { vpc_zone_identifier = length(var.subnets) > 0 ? var.subnets : ( var.use_default_subnets ? data.aws_subnets.default[0].ids : aws_subnet.this.*.id ) + + dynamic "tag" { + for_each = local.tags + + content { + key = tag.key + value = tag.value + propagate_at_launch = true + } + } } From c38dc3292983434d9c5c1ec608f73d55ba518a1d Mon Sep 17 00:00:00 2001 From: Ondrej Smola Date: Tue, 15 Apr 2025 15:18:02 +0200 Subject: [PATCH 3/9] working --- iam.tf | 2 +- iam_pb.tf | 383 +++++++++++++++++++++++++++++++++++++++++++++++++++ main.tf | 23 +++- output.tf | 9 ++ variables.tf | 23 +++- 5 files changed, 435 insertions(+), 5 deletions(-) create mode 100644 iam_pb.tf create mode 100644 output.tf diff --git a/iam.tf b/iam.tf index 81a1d55..d3ecec2 100644 --- a/iam.tf +++ b/iam.tf @@ -18,7 +18,7 @@ resource "aws_iam_role" "this" { name = "${local.name}-instance" description = "Role assumed by EC2 instance(s) running altinity/cloud-connect" - permissions_boundary = var.permissions_boundary + permissions_boundary = var.permission_boundary ? one(aws_iam_policy.altinity-permission-boundary).arn: null assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ diff --git a/iam_pb.tf b/iam_pb.tf new file mode 100644 index 0000000..2f275f2 --- /dev/null +++ b/iam_pb.tf @@ -0,0 +1,383 @@ + + +data "aws_iam_policy_document" "perm-boundary-policy" { + count = var.permission_boundary ? 1 : 0 + + statement { + sid = "DescribeResourcesInRegion" + actions = [ + "ec2:Describe*", + "autoscaling:Describe*", + "elasticloadbalancing:Describe*", + "route53:ListHostedZonesByVPC" + ] + + resources = ["*"] + } + + statement { + sid = "MessageGatewayServiceInRegion" + + actions = [ + "ssmmessages:CreateControlChannel", + "ssmmessages:CreateDataChannel", + "ssmmessages:OpenControlChannel", + "ssmmessages:OpenDataChannel", + ] + + resources = ["*"] + } + + statement { + sid = "EnvRequestTagBasedAccess" + + actions = [ + "ec2:CreateVpc", + "ec2:CreateInternetGateway", + "ec2:CreateRoute", + "ec2:CreateRouteTable", + "ec2:CreateVpcEndpoint", + "ec2:CreateSubnet", + "ec2:RunInstances", + "ec2:CreateLaunchTemplate", + "ec2:CreateVolume", + "ec2:CreateNetworkInterface", + "ec2:CreateSecurityGroup", + "ec2:AllocateAddress", + "ec2:CreateNatGateway", + "ec2:CreateVpcEndpointServiceConfiguration", + "ec2:CreateVpcPeeringConnection", + ] + + resources = ["*"] + + condition { + test = "ForAnyValue:StringEquals" + values = [var.env_name] + variable = "aws:RequestTag/altinity:cloud/env" + } + } + + statement { + effect = "Deny" + + sid = "DenyTagsModificationOnNonManagedResources" + + actions = [ + "ec2:CreateTags", + ] + + resources = ["*"] + + condition { + test = "ForAnyValue:StringNotEquals" + values = [var.env_name] + variable = "aws:ResourceTag/altinity:cloud/env" + } + } + + statement { + sid = "EnvCreateRequestTagBasedAccess" + + actions = [ + "ec2:CreateTags", + ] + + resources = ["*"] + + condition { + test = "ForAnyValue:StringEquals" + values = [ + "CreateVpc", + "CreateInternetGateway", + "CreateRoute", + "CreateRouteTable", + "CreateVpcEndpoint", + "CreateSubnet", + "RunInstances", + "CreateLaunchTemplate", + "CreateVolume", + "CreateNetworkInterface", + "CreateSecurityGroup", + "AllocateAddress", + "CreateNatGateway", + "CreateVpcEndpointServiceConfiguration", + "CreateVpcPeeringConnection", + ] + variable = "ec2:CreateAction" + } + } + + + statement { + sid = "EnvResourceTagBasedAccess" + + actions = [ + "ssm:*", + "ec2:*", + "eks:*", + "iam:*", + "ssm:*", + "lambda:*", + "autoscaling:*", + "elasticloadbalancing:*", + ] + + resources = ["*"] + + condition { + test = "ForAnyValue:StringEquals" + values = [var.env_name] + variable = "aws:ResourceTag/altinity:cloud/env" + } + } + + # https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazoneksauth.html#amazoneksauth-cluster + statement { + sid = "EKSPodIdentity" + + actions = [ + "eks-auth:AssumeRoleForPodIdentity", + ] + + resources = [ + "arn:aws:eks:${local.region}:${local.account_id}:cluster/${local.resource_prefix}" + ] + } + + statement { + sid = "EKSDescribeCluster" + + actions = [ + "eks:DescribeCluster", + ] + + resources = [ + "arn:aws:eks:${local.region}:${local.account_id}:cluster/${local.resource_prefix}" + ] + + } + + statement { + sid = "EKSNodePoolsAMIs" + + actions = [ + "ec2:RunInstances", + ] + resources = ["arn:aws:ec2:${local.region}::image/ami-*"] + + condition { + test = "ForAnyValue:StringEquals" + values = ["amazon"] + variable = "ec2:Owner" + } + } + + statement { + sid = "EKSNodesImages" + + actions = [ + "ecr:GetAuthorizationToken", + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage", + ] + + resources = ["*"] + } + + statement { + sid = "EKSOpenIDConnectProvider" + actions = [ + "iam:GetOpenIDConnectProvider", + ] + + resources = ["arn:aws:iam::${local.account_id}:oidc-provider/oidc.eks.${local.region}.amazonaws.com/id/*"] + } + + statement { + sid = "EKSNodeGroups" + + actions = [ + "eks:DescribeNodegroup", + ] + + resources = ["arn:aws:eks:${local.region}:${local.account_id}:nodegroup/${local.resource_prefix}/*"] + } + + statement { + sid = "EKSAutoscalingGroups" + + actions = [ + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:CreateOrUpdateTags", + ] + + resources = ["*"] + + condition { + test = "ForAnyValue:StringEquals" + values = [local.resource_prefix] + variable = "aws:ResourceTag/eks:cluster-name" + } + } + + statement { + sid = "EKSTagSecurityGroup" + + actions = [ + "ec2:CreateTags" + ] + + resources = ["arn:aws:ec2:${local.region}:${local.account_id}:security-group/*"] + + condition { + test = "ForAnyValue:StringEquals" + values = [local.resource_prefix] + variable = "aws:ResourceTag/aws:eks:cluster-name" + } + } + + statement { + sid = "EKSIAMRole" + + actions = [ + "iam:GetRole", + ] + + resources = [ + "arn:aws:iam::${local.account_id}:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup" + ] + } + + + statement { + sid = "S3" + + actions = [ + "s3:*", + ] + + resources = ["arn:aws:s3:::${local.resource_prefix}-*"] + } + + statement { + sid = "Lambda" + + actions = [ + "lambda:*", + ] + + resources = [ + "arn:aws:lambda:${local.region}:${local.account_id}:function:${local.resource_prefix}-*" + ] + } + + // Not possible to condition + // See https://repost.aws/questions/QUbx7pdp-qTWWOiUb-WtEhFQ/resource-handler-returned-message-the-provided-execution-role-does-not-have-permissions-to-call-createnetworkinterface-on-ec2-service-lambda-status-code-400 + statement { + sid = "LambdaNetworkInterface" + + actions = [ + "ec2:CreateNetworkInterface", + "ec2:DeleteNetworkInterface", + ] + + resources = ["*"] + } + + + statement { + sid = "EnvAssumeAndPassCreatedRoles" + + actions = [ + "sts:AssumeRole", + "sts:AssumeRoleWithWebIdentity", + "iam:PassRole", + ] + + resources = [ + "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}-*" + ] + } + + + statement { + sid = "EnvIAMEntities" + + actions = [ + "iam:*" + ] + + resources = [ + "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}-*", + "arn:aws:iam::${local.account_id}:user/${local.resource_prefix}-*", + "arn:aws:iam::${local.account_id}:instance-profile/${local.resource_prefix}-*", + "arn:aws:iam::${local.account_id}:policy/${local.resource_prefix}-*", + ] + } + + + statement { + sid = "RequirePermissionBoundaryForCreatedRoles" + + actions = [ + "iam:CreateRole", + "iam:AttachRolePolicy", + "iam:PutRolePermissionsBoundary", + "iam:PutRolePolicy", + ] + resources = [ + "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}-*" + ] + condition { + test = "StringEquals" + variable = "iam:PermissionsBoundary" + + values = [ + "arn:aws:iam::${local.account_id}:policy/${local.permission_boundary_policy_name}" + ] + } + } + + statement { + sid = "DenyPermissionBoundaryChanges" + + effect = "Deny" + + actions = [ + "iam:CreatePolicyVersion", + "iam:DeletePolicy", + "iam:DeletePolicyVersion", + "iam:SetDefaultPolicyVersion" + ] + + resources = [ + "arn:aws:iam::${local.account_id}:policy/${local.permission_boundary_policy_name}" + ] + } + + dynamic "statement" { + for_each = var.allow_altinity_access ? [1] : [] + + content { + sid = "BreakGlass" + + actions = [ + "ssm:StartSession", + ] + + resources = [ + "arn:aws:ssm:*:*:document/SSM-SessionManagerRunShell" + ] + } + } +} + +resource "aws_iam_policy" "altinity-permission-boundary" { + count = var.permission_boundary ? 1 : 0 + name = local.permission_boundary_policy_name + description = "Altinity permission boundary for env ${var.env_name}" + policy = one(data.aws_iam_policy_document.perm-boundary-policy).json +} + diff --git a/main.tf b/main.tf index 0796261..6876542 100644 --- a/main.tf +++ b/main.tf @@ -4,14 +4,35 @@ locals { name = "altinitycloud-connect-${random_id.this.hex}" tags = merge(var.tags, { Name = local.name + "altinity:cloud/env" = var.env_name }) } +data "aws_region" "current" {} + +data "aws_caller_identity" "current" {} + +locals { + region = var.region != "" ? var.region : data.aws_region.current.name + account_id = var.aws_account_id != "" ? var.aws_account_id : data.aws_caller_identity.current.account_id +} + resource "random_id" "this" { byte_length = 7 } -data "aws_region" "current" {} +resource "random_string" "resource_suffix" { + count = var.permission_boundary ? 1 : 0 + length = 8 + special = false + upper = false +} + +locals { + env_prefix_base = length(var.env_name) > 8 ? "${substr(var.env_name, 0, 4)}${substr(var.env_name, length(var.env_name) - 4, 4)}" : var.env_name + resource_prefix = var.permission_boundary ? "${local.env_prefix_base}-${one(random_string.resource_suffix).result}" : null + permission_boundary_policy_name = var.permission_boundary ? "${var.env_name}-boundary" : null +} data "aws_ec2_instance_type" "current" { instance_type = var.instance_type diff --git a/output.tf b/output.tf new file mode 100644 index 0000000..2357b2c --- /dev/null +++ b/output.tf @@ -0,0 +1,9 @@ +output "resource_prefix" { + value = var.permission_boundary ? local.resource_prefix : null + description = "AWS resource prefix, only set if permission boundary is enabled" +} + +output "permission_boundary_policy_arn" { + value = var.permission_boundary ? one(aws_iam_policy.altinity-permission-boundary).arn : null + description = "The ARN of the permission boundary policy" +} diff --git a/variables.tf b/variables.tf index 60bd1e6..e0e9b21 100644 --- a/variables.tf +++ b/variables.tf @@ -120,8 +120,25 @@ variable "ec2_security_group_ids" { description = "List of security group IDs to attach. If empty, the default SG is used." } -variable "permissions_boundary" { +variable "permission_boundary" { + type = bool + description = "Enable permission boundary for the IAM role." + default = false +} + +variable "env_name" { type = string - description = "The IAM permissions boundary to attach to the IAM role." - default = "" + description = "Environment name" +} + +variable "region" { + type = string + description = "AWS region" + default = "" +} + +variable "aws_account_id" { + type = string + description = "AWS account ID" + default = "" } From d018f312a4effa14e97fc2804e8a5814fe9180fc Mon Sep 17 00:00:00 2001 From: Ondrej Smola Date: Tue, 15 Apr 2025 15:21:58 +0200 Subject: [PATCH 4/9] cleanup --- iam.tf | 1 - iam_pb.tf | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/iam.tf b/iam.tf index d3ecec2..8124aac 100644 --- a/iam.tf +++ b/iam.tf @@ -17,7 +17,6 @@ data "aws_partition" "current" {} resource "aws_iam_role" "this" { name = "${local.name}-instance" description = "Role assumed by EC2 instance(s) running altinity/cloud-connect" - permissions_boundary = var.permission_boundary ? one(aws_iam_policy.altinity-permission-boundary).arn: null assume_role_policy = jsonencode({ Version = "2012-10-17", diff --git a/iam_pb.tf b/iam_pb.tf index 2f275f2..a0b8aef 100644 --- a/iam_pb.tf +++ b/iam_pb.tf @@ -132,7 +132,6 @@ data "aws_iam_policy_document" "perm-boundary-policy" { } } - # https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazoneksauth.html#amazoneksauth-cluster statement { sid = "EKSPodIdentity" @@ -155,7 +154,6 @@ data "aws_iam_policy_document" "perm-boundary-policy" { resources = [ "arn:aws:eks:${local.region}:${local.account_id}:cluster/${local.resource_prefix}" ] - } statement { @@ -250,7 +248,6 @@ data "aws_iam_policy_document" "perm-boundary-policy" { ] } - statement { sid = "S3" @@ -273,8 +270,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { ] } - // Not possible to condition - // See https://repost.aws/questions/QUbx7pdp-qTWWOiUb-WtEhFQ/resource-handler-returned-message-the-provided-execution-role-does-not-have-permissions-to-call-createnetworkinterface-on-ec2-service-lambda-status-code-400 + // Not possible to set boundary until EKS lambda is replaced statement { sid = "LambdaNetworkInterface" @@ -286,7 +282,6 @@ data "aws_iam_policy_document" "perm-boundary-policy" { resources = ["*"] } - statement { sid = "EnvAssumeAndPassCreatedRoles" @@ -301,7 +296,6 @@ data "aws_iam_policy_document" "perm-boundary-policy" { ] } - statement { sid = "EnvIAMEntities" @@ -317,7 +311,6 @@ data "aws_iam_policy_document" "perm-boundary-policy" { ] } - statement { sid = "RequirePermissionBoundaryForCreatedRoles" From 9a64eb52d91f108ff4cb9195bf71377b92aa0dfe Mon Sep 17 00:00:00 2001 From: Ondrej Smola Date: Wed, 16 Apr 2025 13:41:41 +0200 Subject: [PATCH 5/9] review --- README.md | 2 ++ iam.tf | 10 ++++---- iam_pb.tf | 41 +++++++++++++++----------------- main.tf | 61 +++++++++++++++++++++++++++++------------------- user-data.sh.tpl | 2 +- variables.tf | 13 ++++------- 6 files changed, 67 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 4887e21..d1f953f 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ provider "aws" { # https://registry.terraform.io/providers/hashicorp/aws/latest/docs } + + module "altinitycloud_connect_aws" { source = "altinity/connect-aws/altinitycloud" version = "0.1.0" diff --git a/iam.tf b/iam.tf index 8124aac..5df61ba 100644 --- a/iam.tf +++ b/iam.tf @@ -1,5 +1,3 @@ - - locals { managed_policies = [ "arn:${data.aws_partition.current.partition}:iam::aws:policy/IAMFullAccess", @@ -15,9 +13,9 @@ locals { data "aws_partition" "current" {} resource "aws_iam_role" "this" { - name = "${local.name}-instance" - description = "Role assumed by EC2 instance(s) running altinity/cloud-connect" - permissions_boundary = var.permission_boundary ? one(aws_iam_policy.altinity-permission-boundary).arn: null + name = "${local.name}-instance" + description = "Role assumed by EC2 instance(s) running altinity/cloud-connect" + permissions_boundary = var.permission_boundary ? one(aws_iam_policy.altinity-permission-boundary).arn : null assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ @@ -111,7 +109,7 @@ resource "aws_iam_role_policy" "altinity_break_glass_policy" { role = aws_iam_role.altinity_break_glass[count.index].id policy = jsonencode({ - Version = "2012-10-17", + Version = "2012-10-17", Statement = [ { Effect = "Allow", diff --git a/iam_pb.tf b/iam_pb.tf index a0b8aef..c4888e4 100644 --- a/iam_pb.tf +++ b/iam_pb.tf @@ -1,5 +1,3 @@ - - data "aws_iam_policy_document" "perm-boundary-policy" { count = var.permission_boundary ? 1 : 0 @@ -53,7 +51,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { condition { test = "ForAnyValue:StringEquals" - values = [var.env_name] + values = [local.env_name] variable = "aws:RequestTag/altinity:cloud/env" } } @@ -71,7 +69,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { condition { test = "ForAnyValue:StringNotEquals" - values = [var.env_name] + values = [local.env_name] variable = "aws:ResourceTag/altinity:cloud/env" } } @@ -86,7 +84,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { resources = ["*"] condition { - test = "ForAnyValue:StringEquals" + test = "ForAnyValue:StringEquals" values = [ "CreateVpc", "CreateInternetGateway", @@ -127,7 +125,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { condition { test = "ForAnyValue:StringEquals" - values = [var.env_name] + values = [local.env_name] variable = "aws:ResourceTag/altinity:cloud/env" } } @@ -166,7 +164,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { condition { test = "ForAnyValue:StringEquals" - values = ["amazon"] + values = ["amazon"] variable = "ec2:Owner" } } @@ -215,7 +213,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { condition { test = "ForAnyValue:StringEquals" - values = [local.resource_prefix] + values = [local.resource_prefix] variable = "aws:ResourceTag/eks:cluster-name" } } @@ -231,7 +229,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { condition { test = "ForAnyValue:StringEquals" - values = [local.resource_prefix] + values = [local.resource_prefix] variable = "aws:ResourceTag/aws:eks:cluster-name" } } @@ -255,7 +253,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { "s3:*", ] - resources = ["arn:aws:s3:::${local.resource_prefix}-*"] + resources = ["arn:aws:s3:::${local.resource_prefix}*"] } statement { @@ -266,7 +264,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { ] resources = [ - "arn:aws:lambda:${local.region}:${local.account_id}:function:${local.resource_prefix}-*" + "arn:aws:lambda:${local.region}:${local.account_id}:function:${local.resource_prefix}*" ] } @@ -292,7 +290,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { ] resources = [ - "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}-*" + "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}*" ] } @@ -304,10 +302,10 @@ data "aws_iam_policy_document" "perm-boundary-policy" { ] resources = [ - "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}-*", - "arn:aws:iam::${local.account_id}:user/${local.resource_prefix}-*", - "arn:aws:iam::${local.account_id}:instance-profile/${local.resource_prefix}-*", - "arn:aws:iam::${local.account_id}:policy/${local.resource_prefix}-*", + "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}*", + "arn:aws:iam::${local.account_id}:user/${local.resource_prefix}*", + "arn:aws:iam::${local.account_id}:instance-profile/${local.resource_prefix}*", + "arn:aws:iam::${local.account_id}:policy/${local.resource_prefix}*", ] } @@ -321,7 +319,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { "iam:PutRolePolicy", ] resources = [ - "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}-*" + "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}*" ] condition { test = "StringEquals" @@ -368,9 +366,8 @@ data "aws_iam_policy_document" "perm-boundary-policy" { } resource "aws_iam_policy" "altinity-permission-boundary" { - count = var.permission_boundary ? 1 : 0 - name = local.permission_boundary_policy_name - description = "Altinity permission boundary for env ${var.env_name}" - policy = one(data.aws_iam_policy_document.perm-boundary-policy).json + count = var.permission_boundary ? 1 : 0 + name = local.permission_boundary_policy_name + description = "Altinity permission boundary for env ${local.env_name}" + policy = one(data.aws_iam_policy_document.perm-boundary-policy).json } - diff --git a/main.tf b/main.tf index 6876542..d468076 100644 --- a/main.tf +++ b/main.tf @@ -1,19 +1,34 @@ +data "aws_ssm_parameter" "this" { + count = var.pem_ssm_parameter_name != "" ? 1 : 0 + name = var.pem_ssm_parameter_name +} + +data "tls_certificate" "env_pem" { + content = var.pem_ssm_parameter_name != "" ? one(data.aws_ssm_parameter.this).value : var.pem +} + locals { - ami_name = var.ami_name != "" ? var.ami_name : "al2023-ami-2023.2.20231113.0-kernel-6.1-${data.aws_ec2_instance_type.current.supported_architectures[0]}" + env_name = regex("CN=([^,]+)", data.tls_certificate.env_pem.certificates[0].subject)[0] + ami_name = (var.ami_name != "" ? var.ami_name : + "al2023-ami-2023.2.20231113.0-kernel-6.1-${data.aws_ec2_instance_type.current.supported_architectures[0]}") name = "altinitycloud-connect-${random_id.this.hex}" tags = merge(var.tags, { - Name = local.name - "altinity:cloud/env" = var.env_name + Name = local.name + "altinity:cloud/env" = local.env_name }) } +output "env_name" { + value = local.env_name +} + data "aws_region" "current" {} data "aws_caller_identity" "current" {} locals { - region = var.region != "" ? var.region : data.aws_region.current.name + region = var.region != "" ? var.region : data.aws_region.current.name account_id = var.aws_account_id != "" ? var.aws_account_id : data.aws_caller_identity.current.account_id } @@ -21,19 +36,13 @@ resource "random_id" "this" { byte_length = 7 } -resource "random_string" "resource_suffix" { - count = var.permission_boundary ? 1 : 0 +resource "random_string" "resource_prefix" { + count = var.permission_boundary ? 1 : 0 length = 8 special = false upper = false } -locals { - env_prefix_base = length(var.env_name) > 8 ? "${substr(var.env_name, 0, 4)}${substr(var.env_name, length(var.env_name) - 4, 4)}" : var.env_name - resource_prefix = var.permission_boundary ? "${local.env_prefix_base}-${one(random_string.resource_suffix).result}" : null - permission_boundary_policy_name = var.permission_boundary ? "${var.env_name}-boundary" : null -} - data "aws_ec2_instance_type" "current" { instance_type = var.instance_type } @@ -65,7 +74,7 @@ resource "aws_ssm_parameter" "this" { type = "String" value = var.pem tier = "Intelligent-Tiering" - tags = local.tags + tags = local.tags } resource "aws_ssm_parameter" "ca_crt" { @@ -74,12 +83,15 @@ resource "aws_ssm_parameter" "ca_crt" { type = "String" value = var.ca_crt tier = "Intelligent-Tiering" - tags = local.tags + tags = local.tags } -data "aws_ssm_parameter" "this" { - count = var.pem_ssm_parameter_name != "" ? 1 : 0 - name = var.pem_ssm_parameter_name +locals { + resource_prefix_base = (length(local.env_name) > 8 ? + "${substr(local.env_name, 0, 4)}${substr(local.env_name, length(local.env_name) - 4, 4)}" : local.env_name) + resource_prefix = (var.permission_boundary ? + "${local.resource_prefix_base}-${one(random_string.resource_prefix).result}" : null) + permission_boundary_policy_name = var.permission_boundary ? "${local.env_name}-boundary" : null } resource "aws_launch_template" "this" { @@ -105,11 +117,12 @@ resource "aws_launch_template" "this" { } user_data = base64encode( templatefile("${path.module}/user-data.sh.tpl", { - image = var.image, - ssm_parameter_name = var.pem_ssm_parameter_name != "" ? data.aws_ssm_parameter.this[0].name : aws_ssm_parameter.this[0].name - url = var.url + image = var.image, + ssm_parameter_name = (var.pem_ssm_parameter_name != "" ? data.aws_ssm_parameter.this[0].name : + aws_ssm_parameter.this[0].name) + url = var.url ca_crt_ssm_parameter_name = var.ca_crt != "" ? aws_ssm_parameter.ca_crt[0].name : "" - host_aliases = var.host_aliases + host_aliases = var.host_aliases asg_name = local.name asg_hook_name = "launch" @@ -154,9 +167,9 @@ resource "aws_autoscaling_group" "this" { for_each = local.tags content { - key = tag.key - value = tag.value - propagate_at_launch = true + key = tag.key + value = tag.value + propagate_at_launch = true } } } diff --git a/user-data.sh.tpl b/user-data.sh.tpl index 6caaa6e..4cf7612 100644 --- a/user-data.sh.tpl +++ b/user-data.sh.tpl @@ -29,7 +29,7 @@ aws ssm get-parameter --name "${ca_crt_ssm_parameter_name}" --with-decryption -- docker run -d --name=altinitycloud-connect --restart=always -v /etc/altinitycloud:/etc/altinitycloud:rw --network=host \ %{ for host, alias in host_aliases } --add-host="${host}:${alias}" %{ endfor } "${image}" \ --url=${url} -i /etc/altinitycloud/cloud-connect.pem %{ if ca_crt_ssm_parameter_name != "" } --ca-crt=/etc/altinitycloud/ca.pem %{ endif } \ - --capability aws --dual-tcp-udp + --capability aws aws autoscaling complete-lifecycle-action --lifecycle-action-result CONTINUE --instance-id "$instance" \ diff --git a/variables.tf b/variables.tf index e0e9b21..2ee1eea 100644 --- a/variables.tf +++ b/variables.tf @@ -115,8 +115,8 @@ variable "ami_name" { } variable "ec2_security_group_ids" { - type = list(string) - default = [] + type = list(string) + default = [] description = "List of security group IDs to attach. If empty, the default SG is used." } @@ -126,19 +126,14 @@ variable "permission_boundary" { default = false } -variable "env_name" { - type = string - description = "Environment name" -} - variable "region" { type = string description = "AWS region" - default = "" + default = "" } variable "aws_account_id" { type = string description = "AWS account ID" - default = "" + default = "" } From fe55f27ea22c12f3a13f2e6b759619f9ae010105 Mon Sep 17 00:00:00 2001 From: Ondrej Smola Date: Wed, 16 Apr 2025 14:45:52 +0200 Subject: [PATCH 6/9] remove ssm for ca certificate --- main.tf | 15 +++------------ user-data.sh.tpl | 6 +++--- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/main.tf b/main.tf index d468076..a2eac3a 100644 --- a/main.tf +++ b/main.tf @@ -77,14 +77,6 @@ resource "aws_ssm_parameter" "this" { tags = local.tags } -resource "aws_ssm_parameter" "ca_crt" { - count = var.ca_crt != "" ? 1 : 0 - name = "${local.name}-ca-pem" - type = "String" - value = var.ca_crt - tier = "Intelligent-Tiering" - tags = local.tags -} locals { resource_prefix_base = (length(local.env_name) > 8 ? @@ -120,10 +112,9 @@ resource "aws_launch_template" "this" { image = var.image, ssm_parameter_name = (var.pem_ssm_parameter_name != "" ? data.aws_ssm_parameter.this[0].name : aws_ssm_parameter.this[0].name) - url = var.url - ca_crt_ssm_parameter_name = var.ca_crt != "" ? aws_ssm_parameter.ca_crt[0].name : "" - host_aliases = var.host_aliases - + url = var.url + ca_crt = var.ca_crt + host_aliases = var.host_aliases asg_name = local.name asg_hook_name = "launch" }) diff --git a/user-data.sh.tpl b/user-data.sh.tpl index 4cf7612..6d75f96 100644 --- a/user-data.sh.tpl +++ b/user-data.sh.tpl @@ -22,13 +22,13 @@ mkdir -p /etc/altinitycloud aws ssm get-parameter --name "${ssm_parameter_name}" --with-decryption --query "Parameter.Value" --output text > /etc/altinitycloud/cloud-connect.pem -%{ if ca_crt_ssm_parameter_name != "" } -aws ssm get-parameter --name "${ca_crt_ssm_parameter_name}" --with-decryption --query "Parameter.Value" --output text > /etc/altinitycloud/ca.pem +%{ if ca_crt != "" } +echo "${ca_crt}" > /etc/altinitycloud/ca.pem %{ endif } docker run -d --name=altinitycloud-connect --restart=always -v /etc/altinitycloud:/etc/altinitycloud:rw --network=host \ %{ for host, alias in host_aliases } --add-host="${host}:${alias}" %{ endfor } "${image}" \ - --url=${url} -i /etc/altinitycloud/cloud-connect.pem %{ if ca_crt_ssm_parameter_name != "" } --ca-crt=/etc/altinitycloud/ca.pem %{ endif } \ + --url=${url} -i /etc/altinitycloud/cloud-connect.pem %{ if ca_crt != "" } --ca-crt=/etc/altinitycloud/ca.pem %{ endif } \ --capability aws From 79fd5861deaf5ba9c9422fecd20ab1b75e8b1073 Mon Sep 17 00:00:00 2001 From: Ondrej Smola Date: Wed, 16 Apr 2025 14:50:25 +0200 Subject: [PATCH 7/9] fmt fix --- README.md | 2 -- iam.tf | 3 --- iam_pb.tf | 66 ++++++------------------------------------------------- main.tf | 19 ++++------------ 4 files changed, 11 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index d1f953f..4887e21 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,6 @@ provider "aws" { # https://registry.terraform.io/providers/hashicorp/aws/latest/docs } - - module "altinitycloud_connect_aws" { source = "altinity/connect-aws/altinitycloud" version = "0.1.0" diff --git a/iam.tf b/iam.tf index 5df61ba..de92f7e 100644 --- a/iam.tf +++ b/iam.tf @@ -33,8 +33,6 @@ resource "aws_iam_role" "this" { resource "aws_iam_role_policy" "this" { name = "${aws_iam_role.this.name}-policy" role = aws_iam_role.this.id - - policy = jsonencode({ Version = "2012-10-17", Statement = [ @@ -107,7 +105,6 @@ resource "aws_iam_role_policy" "altinity_break_glass_policy" { count = var.allow_altinity_access ? 1 : 0 name = "${aws_iam_role.altinity_break_glass[count.index].name}-policy" role = aws_iam_role.altinity_break_glass[count.index].id - policy = jsonencode({ Version = "2012-10-17", Statement = [ diff --git a/iam_pb.tf b/iam_pb.tf index c4888e4..fd58eeb 100644 --- a/iam_pb.tf +++ b/iam_pb.tf @@ -9,26 +9,22 @@ data "aws_iam_policy_document" "perm-boundary-policy" { "elasticloadbalancing:Describe*", "route53:ListHostedZonesByVPC" ] - resources = ["*"] } statement { sid = "MessageGatewayServiceInRegion" - actions = [ "ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel", "ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel", ] - resources = ["*"] } statement { sid = "EnvRequestTagBasedAccess" - actions = [ "ec2:CreateVpc", "ec2:CreateInternetGateway", @@ -46,9 +42,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { "ec2:CreateVpcEndpointServiceConfiguration", "ec2:CreateVpcPeeringConnection", ] - resources = ["*"] - condition { test = "ForAnyValue:StringEquals" values = [local.env_name] @@ -58,15 +52,11 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { effect = "Deny" - - sid = "DenyTagsModificationOnNonManagedResources" - + sid = "DenyTagsModificationOnNonManagedResources" actions = [ "ec2:CreateTags", ] - resources = ["*"] - condition { test = "ForAnyValue:StringNotEquals" values = [local.env_name] @@ -76,13 +66,10 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "EnvCreateRequestTagBasedAccess" - actions = [ "ec2:CreateTags", ] - resources = ["*"] - condition { test = "ForAnyValue:StringEquals" values = [ @@ -100,7 +87,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { "AllocateAddress", "CreateNatGateway", "CreateVpcEndpointServiceConfiguration", - "CreateVpcPeeringConnection", + "CreateVpcPeeringConnection" ] variable = "ec2:CreateAction" } @@ -109,7 +96,6 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "EnvResourceTagBasedAccess" - actions = [ "ssm:*", "ec2:*", @@ -118,11 +104,9 @@ data "aws_iam_policy_document" "perm-boundary-policy" { "ssm:*", "lambda:*", "autoscaling:*", - "elasticloadbalancing:*", + "elasticloadbalancing:*" ] - resources = ["*"] - condition { test = "ForAnyValue:StringEquals" values = [local.env_name] @@ -132,11 +116,9 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "EKSPodIdentity" - actions = [ - "eks-auth:AssumeRoleForPodIdentity", + "eks-auth:AssumeRoleForPodIdentity" ] - resources = [ "arn:aws:eks:${local.region}:${local.account_id}:cluster/${local.resource_prefix}" ] @@ -144,9 +126,8 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "EKSDescribeCluster" - actions = [ - "eks:DescribeCluster", + "eks:DescribeCluster" ] resources = [ @@ -156,12 +137,10 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "EKSNodePoolsAMIs" - actions = [ - "ec2:RunInstances", + "ec2:RunInstances" ] resources = ["arn:aws:ec2:${local.region}::image/ami-*"] - condition { test = "ForAnyValue:StringEquals" values = ["amazon"] @@ -171,14 +150,12 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "EKSNodesImages" - actions = [ "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", ] - resources = ["*"] } @@ -187,30 +164,24 @@ data "aws_iam_policy_document" "perm-boundary-policy" { actions = [ "iam:GetOpenIDConnectProvider", ] - resources = ["arn:aws:iam::${local.account_id}:oidc-provider/oidc.eks.${local.region}.amazonaws.com/id/*"] } statement { sid = "EKSNodeGroups" - actions = [ "eks:DescribeNodegroup", ] - resources = ["arn:aws:eks:${local.region}:${local.account_id}:nodegroup/${local.resource_prefix}/*"] } statement { sid = "EKSAutoscalingGroups" - actions = [ "autoscaling:DescribeAutoScalingGroups", "autoscaling:CreateOrUpdateTags", ] - resources = ["*"] - condition { test = "ForAnyValue:StringEquals" values = [local.resource_prefix] @@ -220,13 +191,10 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "EKSTagSecurityGroup" - actions = [ "ec2:CreateTags" ] - resources = ["arn:aws:ec2:${local.region}:${local.account_id}:security-group/*"] - condition { test = "ForAnyValue:StringEquals" values = [local.resource_prefix] @@ -236,11 +204,9 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "EKSIAMRole" - actions = [ "iam:GetRole", ] - resources = [ "arn:aws:iam::${local.account_id}:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup" ] @@ -248,21 +214,17 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "S3" - actions = [ "s3:*", ] - resources = ["arn:aws:s3:::${local.resource_prefix}*"] } statement { sid = "Lambda" - actions = [ "lambda:*", ] - resources = [ "arn:aws:lambda:${local.region}:${local.account_id}:function:${local.resource_prefix}*" ] @@ -271,24 +233,20 @@ data "aws_iam_policy_document" "perm-boundary-policy" { // Not possible to set boundary until EKS lambda is replaced statement { sid = "LambdaNetworkInterface" - actions = [ "ec2:CreateNetworkInterface", "ec2:DeleteNetworkInterface", ] - resources = ["*"] } statement { sid = "EnvAssumeAndPassCreatedRoles" - actions = [ "sts:AssumeRole", "sts:AssumeRoleWithWebIdentity", "iam:PassRole", ] - resources = [ "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}*" ] @@ -296,11 +254,9 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "EnvIAMEntities" - actions = [ "iam:*" ] - resources = [ "arn:aws:iam::${local.account_id}:role/${local.resource_prefix}*", "arn:aws:iam::${local.account_id}:user/${local.resource_prefix}*", @@ -311,7 +267,6 @@ data "aws_iam_policy_document" "perm-boundary-policy" { statement { sid = "RequirePermissionBoundaryForCreatedRoles" - actions = [ "iam:CreateRole", "iam:AttachRolePolicy", @@ -324,7 +279,6 @@ data "aws_iam_policy_document" "perm-boundary-policy" { condition { test = "StringEquals" variable = "iam:PermissionsBoundary" - values = [ "arn:aws:iam::${local.account_id}:policy/${local.permission_boundary_policy_name}" ] @@ -332,17 +286,14 @@ data "aws_iam_policy_document" "perm-boundary-policy" { } statement { - sid = "DenyPermissionBoundaryChanges" - + sid = "DenyPermissionBoundaryChanges" effect = "Deny" - actions = [ "iam:CreatePolicyVersion", "iam:DeletePolicy", "iam:DeletePolicyVersion", "iam:SetDefaultPolicyVersion" ] - resources = [ "arn:aws:iam::${local.account_id}:policy/${local.permission_boundary_policy_name}" ] @@ -350,14 +301,11 @@ data "aws_iam_policy_document" "perm-boundary-policy" { dynamic "statement" { for_each = var.allow_altinity_access ? [1] : [] - content { sid = "BreakGlass" - actions = [ "ssm:StartSession", ] - resources = [ "arn:aws:ssm:*:*:document/SSM-SessionManagerRunShell" ] diff --git a/main.tf b/main.tf index a2eac3a..6b33e5d 100644 --- a/main.tf +++ b/main.tf @@ -7,27 +7,19 @@ data "tls_certificate" "env_pem" { content = var.pem_ssm_parameter_name != "" ? one(data.aws_ssm_parameter.this).value : var.pem } +data "aws_region" "current" {} + +data "aws_caller_identity" "current" {} + locals { env_name = regex("CN=([^,]+)", data.tls_certificate.env_pem.certificates[0].subject)[0] ami_name = (var.ami_name != "" ? var.ami_name : "al2023-ami-2023.2.20231113.0-kernel-6.1-${data.aws_ec2_instance_type.current.supported_architectures[0]}") - name = "altinitycloud-connect-${random_id.this.hex}" tags = merge(var.tags, { Name = local.name "altinity:cloud/env" = local.env_name }) -} - -output "env_name" { - value = local.env_name -} - -data "aws_region" "current" {} - -data "aws_caller_identity" "current" {} - -locals { region = var.region != "" ? var.region : data.aws_region.current.name account_id = var.aws_account_id != "" ? var.aws_account_id : data.aws_caller_identity.current.account_id } @@ -96,7 +88,6 @@ resource "aws_launch_template" "this" { network_interfaces { associate_public_ip_address = var.map_public_ip_on_launch } - vpc_security_group_ids = length(var.ec2_security_group_ids) > 0 ? var.ec2_security_group_ids : null block_device_mappings { device_name = "/dev/xvda" @@ -119,7 +110,6 @@ resource "aws_launch_template" "this" { asg_hook_name = "launch" }) ) - tag_specifications { resource_type = "instance" tags = merge(local.tags, { @@ -156,7 +146,6 @@ resource "aws_autoscaling_group" "this" { dynamic "tag" { for_each = local.tags - content { key = tag.key value = tag.value From a60474a68bcf7a3f230a9a9146b205c98e15074b Mon Sep 17 00:00:00 2001 From: Ondrej Smola Date: Wed, 16 Apr 2025 14:53:45 +0200 Subject: [PATCH 8/9] fmt fix --- iam_pb.tf | 1 - 1 file changed, 1 deletion(-) diff --git a/iam_pb.tf b/iam_pb.tf index fd58eeb..1e9ba04 100644 --- a/iam_pb.tf +++ b/iam_pb.tf @@ -129,7 +129,6 @@ data "aws_iam_policy_document" "perm-boundary-policy" { actions = [ "eks:DescribeCluster" ] - resources = [ "arn:aws:eks:${local.region}:${local.account_id}:cluster/${local.resource_prefix}" ] From 71d19d97b14bedf704b46585eef2b9afe048962f Mon Sep 17 00:00:00 2001 From: Ondrej Smola Date: Tue, 22 Apr 2025 12:21:24 +0200 Subject: [PATCH 9/9] rename --- iam.tf | 2 +- iam_pb.tf | 14 +++++++------- main.tf | 6 +++--- output.tf | 6 +++--- variables.tf | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/iam.tf b/iam.tf index de92f7e..a10c8b6 100644 --- a/iam.tf +++ b/iam.tf @@ -15,7 +15,7 @@ data "aws_partition" "current" {} resource "aws_iam_role" "this" { name = "${local.name}-instance" description = "Role assumed by EC2 instance(s) running altinity/cloud-connect" - permissions_boundary = var.permission_boundary ? one(aws_iam_policy.altinity-permission-boundary).arn : null + permissions_boundary = var.enable_permissions_boundary ? one(aws_iam_policy.altinity-permission-boundary).arn : null assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ diff --git a/iam_pb.tf b/iam_pb.tf index 1e9ba04..e59f766 100644 --- a/iam_pb.tf +++ b/iam_pb.tf @@ -1,5 +1,5 @@ -data "aws_iam_policy_document" "perm-boundary-policy" { - count = var.permission_boundary ? 1 : 0 +data "aws_iam_policy_document" "permissions-boundary-policy" { + count = var.enable_permissions_boundary ? 1 : 0 statement { sid = "DescribeResourcesInRegion" @@ -279,7 +279,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { test = "StringEquals" variable = "iam:PermissionsBoundary" values = [ - "arn:aws:iam::${local.account_id}:policy/${local.permission_boundary_policy_name}" + "arn:aws:iam::${local.account_id}:policy/${local.permissions_boundary_policy_name}" ] } } @@ -294,7 +294,7 @@ data "aws_iam_policy_document" "perm-boundary-policy" { "iam:SetDefaultPolicyVersion" ] resources = [ - "arn:aws:iam::${local.account_id}:policy/${local.permission_boundary_policy_name}" + "arn:aws:iam::${local.account_id}:policy/${local.permissions_boundary_policy_name}" ] } @@ -313,8 +313,8 @@ data "aws_iam_policy_document" "perm-boundary-policy" { } resource "aws_iam_policy" "altinity-permission-boundary" { - count = var.permission_boundary ? 1 : 0 - name = local.permission_boundary_policy_name + count = var.enable_permissions_boundary ? 1 : 0 + name = local.permissions_boundary_policy_name description = "Altinity permission boundary for env ${local.env_name}" - policy = one(data.aws_iam_policy_document.perm-boundary-policy).json + policy = one(data.aws_iam_policy_document.permissions-boundary-policy).json } diff --git a/main.tf b/main.tf index 6b33e5d..ae16a96 100644 --- a/main.tf +++ b/main.tf @@ -29,7 +29,7 @@ resource "random_id" "this" { } resource "random_string" "resource_prefix" { - count = var.permission_boundary ? 1 : 0 + count = var.enable_permissions_boundary ? 1 : 0 length = 8 special = false upper = false @@ -73,9 +73,9 @@ resource "aws_ssm_parameter" "this" { locals { resource_prefix_base = (length(local.env_name) > 8 ? "${substr(local.env_name, 0, 4)}${substr(local.env_name, length(local.env_name) - 4, 4)}" : local.env_name) - resource_prefix = (var.permission_boundary ? + resource_prefix = (var.enable_permissions_boundary ? "${local.resource_prefix_base}-${one(random_string.resource_prefix).result}" : null) - permission_boundary_policy_name = var.permission_boundary ? "${local.env_name}-boundary" : null + permissions_boundary_policy_name = var.enable_permissions_boundary ? "${local.env_name}-boundary" : null } resource "aws_launch_template" "this" { diff --git a/output.tf b/output.tf index 2357b2c..8ed6ccc 100644 --- a/output.tf +++ b/output.tf @@ -1,9 +1,9 @@ output "resource_prefix" { - value = var.permission_boundary ? local.resource_prefix : null + value = var.enable_permissions_boundary ? local.resource_prefix : null description = "AWS resource prefix, only set if permission boundary is enabled" } -output "permission_boundary_policy_arn" { - value = var.permission_boundary ? one(aws_iam_policy.altinity-permission-boundary).arn : null +output "permissions_boundary_policy_arn" { + value = var.enable_permissions_boundary ? one(aws_iam_policy.altinity-permission-boundary).arn : null description = "The ARN of the permission boundary policy" } diff --git a/variables.tf b/variables.tf index 2ee1eea..9de6527 100644 --- a/variables.tf +++ b/variables.tf @@ -120,9 +120,9 @@ variable "ec2_security_group_ids" { description = "List of security group IDs to attach. If empty, the default SG is used." } -variable "permission_boundary" { +variable "enable_permissions_boundary" { type = bool - description = "Enable permission boundary for the IAM role." + description = "Enable permissions boundary for the IAM role." default = false }