【问题标题】:How to create ElasticBeanstalk environment with non-public load balancer with Terraform如何使用 Terraform 使用非公共负载均衡器创建 ElasticBeanstalk 环境
【发布时间】:2017-06-01 14:48:48
【问题描述】:

我正在使用 Terraform 设置 AWS 基础设施。组件之一是具有负载均衡器和自动扩展组的 ElasticBeanstalk 应用程序/环境。我不想将端点暴露给整个 Internet,而只是暴露给有限的 IP 地址列表。为此,我创建了具有适当入站规则的安全组,并将其分配给负载均衡器。但是在应用脚本之后,负载均衡器有两个安全组——一个是我的,另一个是默认的,它允许来自任何地方的 HTTP 流量。 作为临时解决方法,我手动删除了默认 SG 的入站规则。这种方法作为长期解决方案是不可接受的,因为我希望基础设施设置完全自动化(无需任何人工交互)。

这是我的配置:

resource "aws_elastic_beanstalk_environment" "abc_env" {
  name = "abc-${var.environment_name}"
  application = "${aws_elastic_beanstalk_application.abc-service.name}"
  solution_stack_name = "64bit Amazon Linux 2016.09 v2.3.0 running Python 3.4"
  cname_prefix = "abc-${var.environment_name}"
  tier = "WebServer"
  wait_for_ready_timeout = "30m"

  setting {
    name = "InstanceType"
    namespace = "aws:autoscaling:launchconfiguration"
    value = "m3.medium"
  }
  setting {
    name = "SecurityGroups"
    namespace = "aws:elb:loadbalancer"
    value = "${var.limited_http_acccess_id}"
  }
  setting {
    name = "VPCId"
    namespace = "aws:ec2:vpc"
    value = "${var.vpc_id}"
  }
  setting {
    name = "Subnets"
    namespace = "aws:ec2:vpc"
    value = "${var.public_net_id}"
  }
  setting {
    name = "AssociatePublicIpAddress"
    namespace = "aws:ec2:vpc"
    value = "true"
  }
  setting {
    name = "ELBSubnets"
    namespace = "aws:ec2:vpc"
    value = "${var.public_net_id}"
  }
  setting {
    name = "ELBScheme"
    namespace = "aws:ec2:vpc"
    value = "external"
  }

  setting {
    name = "MinSize"
    namespace = "aws:autoscaling:asg"
    value = "2"
  }
  setting {
    name = "MaxSize"
    namespace = "aws:autoscaling:asg"
    value = "4"
  }
  setting {
    name = "Availability Zones"
    namespace = "aws:autoscaling:asg"
    value = "Any 2"
  }
  setting {
    name = "CrossZone"
    namespace = "aws:elb:loadbalancer"
    value = "true"
  }
  setting {
    name = "Unit"
    namespace = "aws:autoscaling:trigger"
    value = "Percent"
  }
  setting {
    name = "MeasureName"
    namespace = "aws:autoscaling:trigger"
    value = "CPUUtilization"
  }
  setting {
    name = "LowerThreshold"
    namespace = "aws:autoscaling:trigger"
    value = "20"
  }
  setting {
    name = "UpperThreshold"
    namespace = "aws:autoscaling:trigger"
    value = "80"
  }
  setting {
    name = "Period"
    namespace = "aws:autoscaling:trigger"
    value = "5"
  }
  setting {
    name = "UpperBreachScaleIncrement"
    namespace = "aws:autoscaling:trigger"
    value = "1"
  }
  setting {
    name = "LowerBreachScaleIncrement"
    namespace = "aws:autoscaling:trigger"
    value = "-1"
  }
  setting {
    name = "Notification Endpoint"
    namespace = "aws:elasticbeanstalk:sns:topics"
    value = "${var.notification_email}"
  }
  tags = "${merge(var.default_tags, map("Name", "abc environment"))}"
}

所以问题是:如何在不与 AWS 手动交互的情况下限制对负载均衡器的访问(仅使用 Terraform 脚本)?

[更新] 这是我的网络配置

resource "aws_vpc" "main_vpc" {
  cidr_block = "${var.vpc_cidr_block}"
  enable_dns_hostnames = true
}

resource "aws_subnet" "public_network" {
  vpc_id = "${aws_vpc.main_vpc.id}"
  cidr_block = "${var.public_network_cidr_block}"
}

resource "aws_internet_gateway" "gateway" {
  vpc_id = "${aws_vpc.main_vpc.id}"
}

resource "aws_route_table" "public" {
  vpc_id = "${aws_vpc.main_vpc.id}"
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = "${aws_internet_gateway.gateway.id}"
  }
}

resource "aws_route_table_association" "public" {
  route_table_id = "${aws_route_table.public.id}"
  subnet_id = "${aws_subnet.public_network.id}"
}

resource "aws_security_group" "limited_http_acccess" {
  name = "limited_http_acccess"
  description = "This security group allows to access resources within VPC from specified IP addresses"
  vpc_id = "${aws_vpc.main_vpc.id}"
  ingress {
    from_port = 80
    to_port = 80
    protocol = "TCP"
    cidr_blocks = ["${split(",", var.allowed_cidr_list)}"]
  }
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

【问题讨论】:

  • 您是否使用 Terraform 管理安全组,如果是,您能否发布您的 SG 配置(当然不包含任何敏感信息)?您需要确保正确定义了 vpc_id、入口和出口块,如果不正确,我已经让 Terraform 做了一些奇怪的事情..
  • 添加了网络配置。对我来说它看起来不错,一切都按预期工作,唯一的事情是我必须手动编辑默认 Beanstalk SG 的入口规则。

标签: amazon-web-services amazon-elastic-beanstalk terraform aws-security-group


【解决方案1】:

根据AWS docs ManagedSecurityGroup 需要添加到 ElasticBeansstalk 配置中,以防止使用默认安全组。

因此,在我的 aws_elastic_beanstalk_environment 中添加以下行解决了问题

  setting {
    name = "ManagedSecurityGroup"
    namespace = "aws:elb:loadbalancer"
    value = "${var.limited_http_acccess_id}"
  }

【讨论】:

  • 我对 ec2 实例上的自动默认安全组有同样的问题(我添加了自己的 aws:autoscaling:launchconfiguration>SecurityGroups),但它总是添加默认值。有人知道如何阻止它吗?
  • @RolfWessels,您可以尝试为负载均衡器使用相同的 SG 并启动配置`设置 { name = "SecurityGroups" namespace = "aws:autoscaling:launchconfiguration" value = "${var.load_balancer_security_group_id }" } 设置 { name = "SecurityGroups" namespace = "aws:elb:loadbalancer" value = "${var.load_balancer_security_group_id}" } 设置 { name = "ManagedSecurityGroup" namespace = "aws:elb:loadbalancer" value = "$ {var.load_balancer_security_group_id}" }`
  • @RollfWessels,但这不是一个好主意。如果您使用 `setting { name = "SSHSourceRestriction" namespace = "aws:autoscaling:launchconfiguration" value = "tcp, 22, 22, ${var. bastion_host_cidr}" }` 所以我看不出有任何理由摆脱它
  • 嗯,我明天试试这些。默认添加对我的 Windows 服务器的 ssh 访问。最终它不是世界末日,但绝对不需要,我讨厌 cloudformation 命名:-)
  • 由于这些问题密切相关,值得指出的是,除了 elb“ManagedSecurityGroup”之外,还有一个“Environment”安全组自动生成并提供 SSH 访问开放的互联网!要关闭它,请参见此处:github.com/terraform-providers/terraform-provider-aws/issues/…
猜你喜欢
  • 2019-09-02
  • 2018-02-10
  • 2019-09-13
  • 2020-01-10
  • 2019-05-08
  • 1970-01-01
  • 2018-09-20
  • 2016-10-30
  • 2020-05-08
相关资源
最近更新 更多