gpt4 book ai didi

amazon-web-services - 用于连接 AWS Cloudwatch 日志、Kinesis Firehose、S3 和 ElasticSearch 的 AWS IAM 策略

转载 作者:行者123 更新时间:2023-11-29 02:47:02 28 4
gpt4 key购买 nike

我正在尝试通过 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,后者被配置为将收到的数据写入 S3 和 ElasticSearch。因此,您正在使用的 AWS 服务正在相互通信,如下所示:

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

    为了让一个 AWS 服务与另一个服务通信,第一个服务必须承担一个角色,授予它这样做的访问权限。在 IAM 术语中,“承担角色”意味着暂时使用授予该角色的权限进行操作。 AWS IAM 角色有两个关键部分:

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

  • 这里需要两个独立的角色。一个角色将授予 Cloudwatch Logs 与 Kinesis Firehose 对话的权限,而第二个角色将授予 Kinesis Firehose 与 S3 和 ElasticSearch 对话的权限。

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

    将 Cloudwatch 日志访问到 Kinesis Firehose

    在问题中给出的示例中, aws_cloudwatch_log_subscription_filter有一个 role_arn谁的 assume_role_policy适用于 AWS Lambda,因此 Cloudwatch Logs 无权承担此角色。

    要解决此问题,可以更改代入角色策略以使用 Cloudwatch 日志的服务名称:
    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 服务访问权限以调用任何 Kinesis Firehose 操作,只要它针对由此 Terraform 配置创建的特定传输流即可。这比严格必要的访问要多;如需更多信息,请参阅 Actions and Condition Context Keys for 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 Delivery Stream 启用日志记录,则很重要,否则 Kinesis Firehose 无法将日志写回 Cloudwatch Logs。

    同样,这比绝对必要的访问更多。有关支持的特定操作的更多信息,请参阅以下引用资料:
  • Action and Context Keys for Amazon S3
  • Grant Firehose Access to an Amazon Elasticsearch Service Destination

  • 由于这个单一角色有权写入 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.comfirehose.amazonaws.com .不幸的是,这些通常记录不充分且很难找到,但通常可以在每个服务的用户指南中的策略示例中找到。
  • 需要授予的操作的名称。每个服务的全套操作可以在 AWS Service Actions and Condition Context Keys for Use in IAM Policies 中找到。 .不幸的是,对于给定的服务到服务集成所需的具体操作的文档通常相当缺乏,但在简单的环境中(尽管有任何严格的监管要求或有关访问的组织政策)通常足以授予对所有操作的访问权限使用上述示例中使用的通配符语法的给定服务。
  • 关于amazon-web-services - 用于连接 AWS Cloudwatch 日志、Kinesis Firehose、S3 和 ElasticSearch 的 AWS IAM 策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43947159/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com