amazon-web-services - 无法使用 terraform 从自动缩放 Hook 创建 sns

标签 amazon-web-services amazon-sns terraform autoscaling

下面的 terraform 脚本应该为自动缩放组的一个堡垒主机创建 sns 主题,并在主机启动或关闭时发送通知。

安全组:

resource "aws_security_group" "ssh_from_authorised_ips" {

          name = "ssh_from_authorised_ips"
          description = "SSH from authorised ip addresses for adminstering bastion host"
          vpc_id = "${var.vpc_id}"

          ingress {
            from_port = 22
            to_port = 22
            protocol = "tcp"
            cidr_blocks = ["192.xx.xx.xx.xx/32", "62.xx.xx.xx/32"]
          }

          egress {
            from_port = 0
            to_port = 0
            protocol = "tcp"
            cidr_blocks = ["0.0.0.0/0"]
          }
          egress {
            from_port = 0
            to_port = 65535
            protocol = "udp"
            cidr_blocks = ["0.0.0.0/0"]
          }

          tags {
            Name = "ssh_from_authorised_ips"
            "om:account_type" = "${var.tag_om_account_type}"
            "om:env" = "${var.tag_om_env}"
            "om:cost_center" = "network"
          }
        }

堡垒脚本:

data "aws_ami" "bastion_ami" {
      most_recent = true

      filter {
        name = "name"
        values = ["testami_*"]
      }

      owners = ["self"]
    }

resource "aws_autoscaling_group" "bastion_asg" {

  lifecycle { create_before_destroy = true }

  vpc_zone_identifier  = ["${split(",", var.public_subnets)}"]

  name = "asg_${aws_launch_configuration.bastion_lc.name}"
  min_size = "1"
  max_size = "1"

  default_cooldown = "180"
  health_check_grace_period = "180"
  health_check_type = "EC2"
  launch_configuration = "${aws_launch_configuration.bastion_lc.id}"

  tags = [
    {
      key = "Name"
      value = "bastion"
      propagate_at_launch = true
    },
    {
      key = "om:account_type"
      value = "${var.tag_om_account_type}"
      propagate_at_launch = true
    }
  ]
}

resource "aws_sns_topic" "bastion_updates" {
  name = "bastion-updates-topic"
  display_name = "Bastion_notification"
}

resource "aws_key_pair" "bastion_key" {
  key_name   =  "bastion_key_name"
  public_key = "${file("/home/xxxxxx/.ssh/id_rsa_bastion.pub")}"
}

resource "aws_launch_configuration" "bastion_lc" {

  lifecycle { create_before_destroy = true }

  name_prefix = "bastion_"
  image_id = "${data.aws_ami.bastion_ami.id}"
  instance_type = "${var.instance_type}"
  associate_public_ip_address = true
  security_groups = ["${split(",", var.security_groups)}"]

  key_name = "${aws_key_pair.bastion_key.key_name}"

  root_block_device {
    volume_type = "gp2"
    volume_size = "${var.volume_size}"
    delete_on_termination = true
  }

}


resource "aws_iam_role" "bastion_notify_role" {
  name = "bastion_notify_role"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_autoscaling_lifecycle_hook" "bastion_down_notify" {
 name                   = "bastion-down"
 autoscaling_group_name = "${aws_autoscaling_group.bastion_asg.name}"
 default_result         = "CONTINUE"
 heartbeat_timeout      = 31
 lifecycle_transition   = "autoscaling:EC2_INSTANCE_TERMINATING"
 notification_metadata = <<EOF
{
 "bastion_message": "Bastion going down."
}
EOF
  notification_target_arn = "${aws_sns_topic.bastion_updates.arn}"
  role_arn                = "${aws_iam_role.bastion_notify_role.arn}"
}


resource "aws_autoscaling_lifecycle_hook" "bastion_up_notify" {
 name                   = "bastion-up"
 autoscaling_group_name = "${aws_autoscaling_group.bastion_asg.name}"
 default_result         = "CONTINUE"
 heartbeat_timeout      = 31
 lifecycle_transition   = "autoscaling:EC2_INSTANCE_LAUNCHING"
 notification_metadata = <<EOF
{
 "bastion_message": "Bastion coming up."
}
EOF
  notification_target_arn = "${aws_sns_topic.bastion_updates.arn}"
  role_arn                = "${aws_iam_role.bastion_notify_role.arn}"
}




----------------------------------------------

当我执行 terraform apply -target=bastion_host 时,出现以下错误。

module.bastion_host.aws_autoscaling_lifecycle_hook.bastion_down_notify: 1 error(s) occurred:

* aws_autoscaling_lifecycle_hook.bastion_down_notify: [DEBUG] Retrying AWS AutoScaling Lifecycle Hook: ValidationError: Unable to publish test message to notification target arn:aws:sns:eu-west-1:031768xxxx:bastion-updates-topic using IAM role arn:aws:iam::0317682xxxxx:role/bastion_notify_role. Please check your target and role configuration and try to put lifecycle hook again.
        status code: 400, request id: ad7379a6-09ca-11e8-85a3-d114xxxxxx
* module.bastion_host.aws_autoscaling_lifecycle_hook.bastion_up_notify: 1 error(s) occurred:

* aws_autoscaling_lifecycle_hook.bastion_up_notify: [DEBUG] Retrying AWS AutoScaling Lifecycle Hook: ValidationError: Unable to publish test message to notification target arn:aws:sns:eu-west-1:03176821xxxx:bastion-updates-topic using IAM role arn:aws:iam::0317682xxx:role/bastion_notify_role. Please check your target and role configuration and try to put lifecycle hook again.
        status code: 400, request id: ad7e4f1a-09ca-11e8-ac2b-2bxxxx

最佳答案

您需要附加到 bastion_notify_role 角色的策略,以允许其发布到 SNS。为此有一个 AWS 托管策略:

resource "aws_iam_role_policy_attachment" "bastion_notify_sns_access" {
  role       = "${aws_iam_role.bastion_notify_role.name}"
  policy_arn = "arn:aws:iam::aws:policy/service-role/AutoScalingNotificationAccessRole"
}

关于amazon-web-services - 无法使用 terraform 从自动缩放 Hook 创建 sns,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48610612/

相关文章:

amazon-web-services - SNS 可以路由到多个 SQS 延迟队列之一吗?

tags - 如何命名使用 terraform 提供的 eks 工作节点?

amazon-s3 - 读取CDK中的bucket对象

amazon-web-services - 如何从其 ARN 中获取 AWS 角色的友好名称?

sql - 如何使用AWS快速分区100亿行SQL表?

python - 如何从 boto 中的 sns 取消订阅 sqs 队列

mysql - 使用 EBS 增加运行 EC2 的存储

php - Amazon SNS 使用 PHP 推送主题

http - 使用 CORS 从远程 Web 客户端调用 AWS API Gateway

bash - k8s CronJob 在 pod 列表上循环