用于连接 AWS Cloudwatch Logs、Kinesis Firehose、S3 和 ElasticSearch 的 AWS IAM 策略

2023-11-25

我正在尝试通过 Kinesis Firehose 将 AWS cloudwatch 日志流式传输到 ES。下面的 terraform 代码给出了错误。有什么建议.. 错误是:

  • aws_cloudwatch_log_subscription_filter.test_kinesis_logfilter:发生 1 个错误:
  • aws_cloudwatch_log_subscription_filter.test_kinesis_logfilter:InvalidParameterException:无法将测试消息传递到指定的 Firehose 流。检查给定的 Firehose 流是否处于 ACTIVE 状态。

resource "aws_s3_bucket" "bucket" {
  bucket = "cw-kinesis-es-bucket"
  acl    = "private"
}

resource "aws_iam_role" "firehose_role" {
  name = "firehose_test_role"

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

resource "aws_elasticsearch_domain" "es" {
  domain_name           = "firehose-es-test"
  elasticsearch_version = "1.5"
  cluster_config {
    instance_type = "t2.micro.elasticsearch"
  }
  ebs_options {
    ebs_enabled = true
    volume_size = 10
  }

  advanced_options {
    "rest.action.multi.allow_explicit_index" = "true"
  }

  access_policies = <<CONFIG
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "es:*",
            "Principal": "*",
            "Effect": "Allow",
            "Condition": {
                "IpAddress": {"aws:SourceIp": ["xxxxx"]}
            }
        }
    ]
}
CONFIG

  snapshot_options {
    automated_snapshot_start_hour = 23
  }

  tags {
    Domain = "TestDomain"
  }
}

resource "aws_kinesis_firehose_delivery_stream" "test_stream" {
  name        = "terraform-kinesis-firehose-test-stream"
  destination = "elasticsearch"

  s3_configuration {
    role_arn           = "${aws_iam_role.firehose_role.arn}"
    bucket_arn         = "${aws_s3_bucket.bucket.arn}"
    buffer_size        = 10
    buffer_interval    = 400
    compression_format = "GZIP"
  }

  elasticsearch_configuration {
    domain_arn = "${aws_elasticsearch_domain.es.arn}"
    role_arn   = "${aws_iam_role.firehose_role.arn}"
    index_name = "test"
    type_name  = "test"
  }
}

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

resource "aws_cloudwatch_log_subscription_filter" "test_kinesis_logfilter" {
  name            = "test_kinesis_logfilter"
  role_arn        = "${aws_iam_role.iam_for_lambda.arn}"
  log_group_name  = "loggorup.log"
  filter_pattern  = ""
  destination_arn = "${aws_kinesis_firehose_delivery_stream.test_stream.arn}"
}


在此配置中,您将指示 Cloudwatch Logs 将日志记录发送到 Kinesis Firehose,而 Kinesis Firehose 又配置​​为将接收到的数据写入 S3 和 ElasticSearch。因此,您正在使用的 AWS 服务之间的交互方式如下:

Cloudwatch Logs talks to Kinesis Firehose, which in turn talks to both S3 and ElasticSearch

为了让一个 AWS 服务与另一个服务对话,第一个服务必须assume授予其执行此操作的权限的角色。在 IAM 术语中,“担任角色”意味着暂时使用授予该角色的权限进行操作。 AWS IAM 角色有两个关键部分:

  • The 承担角色政策,控制哪些服务和/或用户可以承担该角色。
  • 控制角色授予访问权限的策略。这决定了服务或用户在承担该角色后可以做什么。

这里需要两个独立的角色。第一个角色将授予 Cloudwatch Logs 访问权限以与 Kinesis Firehose 通信,而第二个角色将授予 Kinesis Firehose 访问权限以与 S3 和 ElasticSearch 通信。

对于本答案的其余部分,我将假设 Terraform 作为对 AWS 帐户具有完全管理访问权限的用户运行。如果情况并非如此,则首先需要确保 Terraform 作为有权创建和传递角色的 IAM 主体运行。


Cloudwatch 日志对 Kinesis Firehose 的访问

在问题给出的例子中,aws_cloudwatch_log_subscription_filter has a role_arn whose assume_role_policy适用于 AWS Lambda,因此 Cloudwatch Logs 无权承担此角色。

要解决此问题,可以更改代入角色策略以使用 Cloudwatch Logs 的服务名称:

resource "aws_iam_role" "cloudwatch_logs" {
  name = "cloudwatch_logs_to_firehose"
  assume_role_policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Principal": {
          "Service": "logs.us-east-1.amazonaws.com"
        },
        "Effect": "Allow",
        "Sid": "",
      },
    ],
  })
}

上述内容允许 Cloudwatch Logs 服务承担该角色。现在该角色需要一个允许写入 Firehose Delivery Stream 的访问策略:

resource "aws_iam_role_policy" "cloudwatch_logs" {
  role = aws_iam_role.cloudwatch_logs.name

  policy = jsonencode({
    "Statement": [
      {
        "Effect": "Allow",
        "Action": ["firehose:*"],
        "Resource": [aws_kinesis_firehose_delivery_stream.test_stream.arn],
      },
    ],
  })
}

以上授予 Cloudwatch Logs 服务访问权限以调用anyKinesis Firehose 操作,只要它针对此 Terraform 配置创建的特定传输流即可。这超出了严格必要的访问范围;有关更多信息,请参阅Amazon Kinesis Firehose 的操作和条件上下文键.

为了完成这个任务,aws_cloudwatch_log_subscription_filter必须更新资源以引用此新角色:

resource "aws_cloudwatch_log_subscription_filter" "test_kinesis_logfilter" {
  name            = "test_kinesis_logfilter"
  role_arn        = aws_iam_role.cloudwatch_logs.arn
  log_group_name  = "loggorup.log"
  filter_pattern  = ""
  destination_arn = aws_kinesis_firehose_delivery_stream.test_stream.arn

  # Wait until the role has required access before creating
  depends_on = aws_iam_role_policy.cloudwatch_logs
}

不幸的是,由于 AWS IAM 的内部设计,Terraform 提交策略更改后通常需要几分钟才能生效,因此有时在尝试很快使用策略创建新资源时会出现与策略相关的错误在政策本身创建之后。在这种情况下,通常只需等待 10 分钟,然后再次运行 Terraform 就足够了,此时它应该从中断处恢复并重试创建资源。


Kinesis Firehose 访问 S3 和 Amazon ElasticSearch

问题中给出的示例已经具有 IAM 角色,并且具有适合 Kinesis Firehose 的代入角色策略:

resource "aws_iam_role" "firehose_role" {
  name = "firehose_test_role"

  assume_role_policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Principal": {
          "Service": "firehose.amazonaws.com"
        },
        "Effect": "Allow",
        "Sid": ""
      }
    ]
  })
}

上述内容授予 Kinesis Firehose 访问权限来承担此角色。与之前一样,该角色还需要一个访问策略来授予该角色的用户对目标 S3 存储桶的访问权限:

resource "aws_iam_role_policy" "firehose_role" {
  role = aws_iam_role.firehose_role.name

  policy = jsonencode({
    "Statement": [
      {
        "Effect": "Allow",
        "Action": ["s3:*"],
        "Resource": [aws_s3_bucket.bucket.arn]
      },
      {
        "Effect": "Allow",
        "Action": ["es:ESHttpGet"],
        "Resource": ["${aws_elasticsearch_domain.es.arn}/*"]
      },
      {
        "Effect": "Allow",
        "Action": [
            "logs:PutLogEvents"
        ],
        "Resource": [
            "arn:aws:logs:*:*:log-group:*:log-stream:*"
        ]
      },
    ],
  })
}

上述策略允许 Kinesis Firehose 对创建的 S3 存储桶执行任何操作、对创建的 ElasticSearch 域执行任何操作,以及将日志事件写入 Cloudwatch Logs 中的任何日志流。最后一部分并不是绝对必要的,但如果为 Firehose 传输流启用了日志记录,则非常重要,否则 Kinesis Firehose 无法将日志写回 Cloudwatch Logs。

同样,这种访问权限超出了严格必要的范围。有关支持的特定操作的更多信息,请参阅以下参考文献:

  • Amazon S3 的操作和上下文键
  • 授予 Firehose 对 Amazon Elasticsearch Service 目标的访问权限

由于该单一角色有权写入 S3 和 ElasticSearch,因此可以在 Kinesis Firehose 传输流中为这两种传输配置指定它:

resource "aws_kinesis_firehose_delivery_stream" "test_stream" {
  name        = "terraform-kinesis-firehose-test-stream"
  destination = "elasticsearch"

  s3_configuration {
    role_arn           = aws_iam_role.firehose_role.arn
    bucket_arn         = aws_s3_bucket.bucket.arn
    buffer_size        = 10
    buffer_interval    = 400
    compression_format = "GZIP"
  }

  elasticsearch_configuration {
    domain_arn = aws_elasticsearch_domain.es.arn
    role_arn   = aws_iam_role.firehose_role.arn
    index_name = "test"
    type_name  = "test"
  }

  # Wait until access has been granted before creating the firehose
  # delivery stream.
  depends_on = [aws_iam_role_policy.firehose_role]
}

完成上述所有接线后,服务应该具有连接此交付管道各部分所需的访问权限。

这一通用模式适用于两个 AWS 服务之间的任何连接。每个案例所需的重要信息是:

  • 将发起请求的服务的服务名称,例如logs.us-east-1.amazonaws.com or firehose.amazonaws.com。不幸的是,这些内容通常记录很少并且很难找到,但通常可以在每个服务的用户指南中的策略示例中找到。
  • 需要授予的操作的名称。每个服务的完整操作集可以在以下位置找到:用于 IAM 策略的 AWS 服务操作和条件上下文键。不幸的是,专门的文档which给定服务到服务集成所需的操作通常相当缺乏,但在简单的环境中(尽管有任何严格的监管要求或有关访问的组织策略),通常足以使用通配符授予对给定服务的所有操作的访问权限上面示例中使用的语法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用于连接 AWS Cloudwatch Logs、Kinesis Firehose、S3 和 ElasticSearch 的 AWS IAM 策略 的相关文章

随机推荐

  • C 中最快的解交错操作?

    我有一个指向字节数组的指针mixed包含两个不同数组的交错字节array1 and array2 Say mixed看起来像这样 a1b2c3d4 我需要做的是对字节进行去交错 这样我就得到了array1 abcd and array2 1
  • Android 开发:Keytool,创建密钥库?

    我正在尝试为谷歌市场准备我的应用程序 但事实证明它比预期更具挑战性 我似乎无法掌握签署应用程序的整个概念 但更具体地说 我的问题是我已经安装了 Eclipse 的 keytool 插件 但是当我想创建一个证书时 它要求我选择一个密钥库 输入
  • 如何在 OpenCV 中裁剪 CvMat?

    我有一个图像转换为CvMat矩阵说CVMat source 一旦我得到一个感兴趣的区域source我希望算法的其余部分仅应用于该感兴趣的区域 为此 我想我将不得不以某种方式裁剪source我无法这样做的矩阵 有没有一种方法或函数可以裁剪Cv
  • C 中的参数传递 - 指针、地址、别名

    有人可以解释一下参数传递之间的区别吗C请 根据教授的笔记 有 4 种不同的方式来传递参数 按值调用 按地址调用 指针 按别名呼叫 全局变量 静态变量 如果您能举个例子 我将不胜感激 并且您的工作将受到赞扬 按值调用 将值作为参数传递给函数
  • jquery .stop() 不工作

    我正在尝试构建一个菜单 其中默认情况下仅显示第一个项目 当您将鼠标悬停在其上时 其余项目会滑出 并在鼠标离开时再次隐藏 它大部分工作正常 但如果鼠标在完成滑出之前退出 则不会调用隐藏函数 我想stop 本来应该解决这个问题 但似乎没有任何影
  • Python 中内置类型的自定义比较函数

    我正在使用 Python 的内置集合来保存我定义的类的对象 对于这个类 我定义了 eq ne and hash 这样我就可以通过自定义比较函数来比较对象 这很好用 直到我发现我确实需要two比较函数集 这些函数将在我的代码中的不同时间以不同
  • 如何在 jQuery.each 函数的每个循环之间设置延迟?

    我有这样的代码 li each function var data this text requestFunction data function status if status OK do stuff 所以 我需要在使用函数 reque
  • FPU 与软件仿真的性能比较

    虽然我知道 所以我被告知 浮点协处理器的工作速度比任何浮点算术的软件实现都快 但我完全不知道这种差异有多大 以数量级而言 答案可能取决于微处理器和超级计算机之间的应用程序以及您的工作地点 我对计算机模拟特别感兴趣 你能指出这个问题的文章或论
  • Push_swap:使用两个具有有限指令的可旋转堆栈,在 C 中按升序对给定的一组数字进行排序

    我被给予本校 42 项任务 您可以使用一组 int 值 2 个堆栈和一组操作这两个堆栈的指令 用C编写 一个程序 称为push swap它计算并在标准输出上显示最小的程序Push swap对收到的整数参数进行排序的指令语言 sa swap
  • 分析 python 多处理池

    我试图在多处理池中的每个进程上运行 cProfile runctx 以了解我的源中的多处理瓶颈 这是我正在尝试做的事情的简化示例 from multiprocessing import Pool import cProfile def sq
  • 解组期间 XML 字符无效

    我使用编码 UTF 8 将对象编组到 XML 文件 就成功生成文件了 但是当我尝试将其解组回来时 出现错误 无效的 XML 字符 Unicode 0x 2 的值被发现 属性 1 且元素为 0 该字符为 0x1A 或 u001a 在 UTF
  • 检查 Laravel Blade 文件中的变量是否为空

    我有变量 material details gt pricing null我想检查 laravel Blade 文件中设置的变量 我尝试过 isset material details gt pricing tr td price is n
  • ggplot:annotate() 的大小与 element_text() 的大小

    我在协调情节中不同元素的大小方面遇到了一些麻烦 具体来说 我希望注释的大小与 y 轴标题的大小相同 然而 以下代码会产生不同的大小 library ggplot2 test data lt data frame x c 1 y c 1 gg
  • 无法初始化类 com.sun.xml.internal.ws.fault.SOAPFaultBuilder

    我在maven库中使用Jaxb impl 2 1 3 jar 在pom条目中一切看起来都很好 如果有人遇到这个错误 请给我一个想法 java lang reflect InvocationTargetException at sun ref
  • 有没有办法让 PhpStorm 的自动完成“更深入”?

    在 PhpStorm 中 如果我创建一个对象 那么该对象上的所有自动完成功能都可以正常工作 object new MyClass object gt getNa 将自动完成至 object gt getName 到目前为止一切顺利 但如果我
  • 为什么我的抓取 NSE 网站的程序在服务器中被阻止,但在本地却可以运行?

    此 python 代码在本地计算机上运行 但未在 数字海洋 亚马逊AWS 谷歌合作实验室 Heroku 和许多其他 VPS 它在不同时间显示不同的错误 import requests headers authority beta nsein
  • 为什么ARM上有两个向量表地址?

    在ARM架构中 有一个低向量地址0x0和高向量地址0xFFFF0000 我想知道为什么可能需要两个向量地址 在 Intel 微处理器和微控制器中 有一个向量地址 有 2 个向量地址有什么特殊原因吗 某些微控制器系列具有多个不同的起始地址和
  • 从内部类对象获取外部类对象

    简而言之 我正在尝试做相反的事情 classObject getDeclaredClasses 我有一个接收类型对象的方法Class
  • .htaccess 问题:未指定输入文件

    有人可以帮我弄这个吗 我感觉自己已经用头撞墙两个多小时了 我有Apache 2 2 8 PHP 5 2 6安装在我的机器上并且 htaccess下面的代码工作正常 没有错误 RewriteEngine on RewriteCond 1 in
  • 用于连接 AWS Cloudwatch Logs、Kinesis Firehose、S3 和 ElasticSearch 的 AWS IAM 策略

    我正在尝试通过 Kinesis Firehose 将 AWS cloudwatch 日志流式传输到 ES 下面的 terraform 代码给出了错误 有什么建议 错误是 aws cloudwatch log subscription fil