如何使用 Terraform 传递 AssumeRole 并将 SSM 文档与 EC2 相关联

How to pass AssumeRole and associate SSM Document with EC2 using Terraform

我正在尝试将 SSM 文档(将 linux 服务器与 AD 域连接起来)与 EC2 实例相关联。

我在关联过程中收到以下错误 -

aws_ssm_association.rhel: Creating...
╷
│ Error: Error creating SSM association: ValidationException: The assume role is invalid.
│       status code: 400, request id: 3e2e23f0-da9e-4d0d-947f-2f121aa653e9
│ 
│   with aws_ssm_association.rhel,
│   on ssm.tf line 10, in resource "aws_ssm_association" "rhel":
│   10: resource "aws_ssm_association" "rhel" {

这是我的 Terraform 代码 -

main.tf

provider "aws" {
  region              = "us-west-2"
  allowed_account_ids = ["1234"]

  assume_role {
    role_arn = "arn:aws:iam::1234:role/my-role"
  }
}

terraform {
  required_version = "= 1.0.9"
}

ec2.tf

resource "aws_key_pair" "rhel" {
  key_name_prefix = "rhel_domain_join_test"
  public_key      = "ssh-rsa AMAMAMMMxxxx"
}

resource "aws_instance" "rhel" {
  ami                    = "ami-0b28dfc7adc3xxx" # us-west-2
  instance_type          = "t3.medium"
  subnet_id              = "subnet-023db3ebxxx"
  iam_instance_profile   = aws_iam_instance_profile.rhel_instance_profile.id
  vpc_security_group_ids = ["sg-077f9f9aceexxxx"]
  key_name               = aws_key_pair.rhel.id

  tags = {
    Name = "w2domainjointestpoc"
  }
}

iam.tf

resource "aws_iam_instance_profile" "rhel_instance_profile" {
  name_prefix = "rhel_instance_profile"
  role        = aws_iam_role.rhel_instance_role.name
}

resource "aws_iam_role" "rhel_instance_role" {
  name_prefix        = "rhel_instance_role"
  path               = "/"
  assume_role_policy = data.aws_iam_policy_document.ssm_role_policy.json
}

resource "aws_iam_role_policy_attachment" "rhel_instance" {
  role       = aws_iam_role.rhel_instance_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole"
}

resource "aws_iam_role_policy_attachment" "rhel_instance_2" {
  role       = aws_iam_role.rhel_instance_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
}

resource "aws_iam_role_policy_attachment" "ec2-attach" {
  role       = aws_iam_role.rhel_instance_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
}


resource "aws_iam_policy" "ssm_role_passrole" {
  name_prefix = "ssm_automation"
  description = "My test policy"
  policy      = data.aws_iam_policy_document.ssm_role_passrole.json
}

resource "aws_iam_role_policy_attachment" "ssm_role_passrole" {
  role       = aws_iam_role.rhel_instance_role.name
  policy_arn = aws_iam_policy.ssm_role_passrole.arn
}

data.tf

data "aws_iam_policy_document" "ssm_role_policy" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com", "ssm.amazonaws.com"]
    }
  }
}


data "aws_iam_policy_document" "ssm_role_passrole" {
  statement {
    actions   = ["iam:GetRole", "iam:PassRole"]
    resources = [aws_iam_role.rhel_instance_role.arn]
  }
}

ssm.tf

resource "aws_ssm_document" "rhel_domain_join_document" {
  name            = "rhel_domain_join_document"
  document_format = "JSON"
  document_type   = "Automation"


  content = file("${path.module}/redhat_linux_launch_automation_document.json")
}

resource "aws_ssm_association" "rhel" {
  name = aws_ssm_document.rhel_domain_join_document.name

  targets {
    key    = "InstanceIds"
    values = [aws_instance.rhel.id]
  }
}

你能帮我理解我在这里遗漏了什么吗?

谢谢

我认为您混淆了 SSM 文档类型。对于 SSM 状态管理器,您可以使用 三种类型 of documents:

  1. 政策
  2. 命令
  3. 自动化

你的redhat_linux_launch_automation_document.json是一个自动化。因此,aws_ssm_association.rhel 中的 targets 块并不完全适用。 targets 块仅针对前两种文档类型或速率受控 Automation.

对于 自动化类型 的简单执行,您只需在 aws_ssm_association.rhel 中提供 parameters,假设您不需要任何速率或计划执行控制。此外,您的 redhat_linux_launch_automation_document.json 没有 担任任何角色

所以应该是:

redhat_linux_launch_automation_document.json(局部视图)

添加角色AutomationAssumeRole:

{
    "description": "Launch Automation for RedHat Linux instance",
    "schemaVersion": "0.3",
    "assumeRole": "{{AutomationAssumeRole}}",    
    "parameters": {
        "instanceIds": {
            "type": "StringList",
            "description": "InstanceIds to run launch setup"
        },
        "AutomationAssumeRole": {
          "default": "",
          "type": "String",
          "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf."
        }        
    },

main.tf:

创建 SSM 角色:

resource "aws_iam_role" "ssm" {
  path               = "/"
  assume_role_policy = <<EOL
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": ["ec2.amazonaws.com", "ssm.amazonaws.com"]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOL

  managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole"]

  inline_policy {
    name = "my_inline_policy"

    policy = jsonencode({
      Version = "2012-10-17"
      Statement = [
        {
          Action   = ["iam:PassRole"]
          Effect   = "Allow"
          Resource = "*"
        },
      ]
    })
  }

}

最后修正 aws_ssm_association.rhel:

resource "aws_ssm_association" "rhel" {

  name = aws_ssm_document.rhel_domain_join_document.name
  
  parameters = {
      AutomationAssumeRole = aws_iam_role.ssm.arn
      instanceIds = aws_instance.rhel.id
  }  
}

注意:我的回答仅针对您的错误消息。我没有检查您的自动化文档是否真的有效。为此,您可能需要创建新问题。