首页 > 解决方案 > 如何使用 Terraform 传递 AssumeRole 并将 SSM 文档与 EC2 关联

问题描述

我正在尝试将 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 代码 -

主文件

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
}

数据.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文件

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]
  }
}

你能帮我理解我在这里缺少什么吗?

谢谢

标签: amazon-web-servicesamazon-ec2terraformaws-ssm

解决方案


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

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

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

对于您只需提供的自动化类型的简单执行,假设您不需要任何速率或计划执行控制。你也不承担任何角色parametersaws_ssm_association.rhelredhat_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."
        }        
    },

主文件

创建 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
  }  
}

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


推荐阅读