通过 terraform 将 EC2 实例加入 AD 域

ve0*_*ibu 2 active-directory terraform ssm terraform-provider-aws

我希望你能帮助我解决我的问题。我正在尝试自动让我的 ec2 实例使用我的 terraform 脚本加入一个广告域。由于 Terraform 不支持任何“域加入目录”选项,我想尝试创建一个 SSM 文档,让 Systems Manager 为我制作。实际上我得到了以下代码:

resource "aws_directory_service_directory" "ad" {
  name     = "active-directory-service.com"
  password = "${var.ad-password}"
  edition  = "Standard"
  size     = "Small"
  type     = "MicrosoftAD"

  vpc_settings {
    vpc_id     = "${aws_vpc.vpc.id}"
    subnet_ids = ["${aws_subnet.ds-subnet.0.id}", 
                  "${aws_subnet.ds-subnet.1.id}"
                  ]
  }

}

resource "aws_vpc_dhcp_options" "vpc-dhcp-options" {
  domain_name          = "${var.dir_domain_name}"
  domain_name_servers  = aws_directory_service_directory.ad.dns_ip_addresses

}
resource "aws_vpc_dhcp_options_association" "dns_resolver" {
   vpc_id          =  aws_vpc.vpc.id
   dhcp_options_id = aws_vpc_dhcp_options.vpc-dhcp-options.id
}

resource "aws_ssm_document" "ad-server-domain-join-document" {
    name  = "myapp_dir_default_doc"
    document_type = "Command"

content = <<DOC
{
        "schemaVersion": "1.0",
        "description": "Join an instance to a domain",
        "runtimeConfig": {
           "aws:domainJoin": {
               "properties": {
                  "directoryId": "${aws_directory_service_directory.ad.id}",
                  "directoryName": "${var.dir_domain_name}",
                  "directoryOU": "${var.dir_computer_ou}",
                  "dnsIpAddresses": [
                     "${aws_directory_service_directory.ad.dns_ip_addresses[0]}",
                     "${aws_directory_service_directory.ad.dns_ip_addresses[1]}"
               }
           }
        }
}
DOC
}

resource "aws_ssm_association" "ad-server-association" {
    name = "dir_default_doc"
    instance_id = aws_instance.ec2-ad-instance.id
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误消息:

该值没有任何索引。有人可以告诉我如何解决这个问题吗?

小智 6

如果您使用的 AMI 没有 SSM,您可以这样做:

user_data = <<EOF
<powershell>
Add-Computer -DomainName 'NAME_OF_THE_DOMAIN' -NewName 'NEW_NAME_OF_THE_MACHINE' -Credential (New-Object -TypeName PSCredential -ArgumentList "DOMAIN_USERNAME",(ConvertTo-SecureString -String 'DOMAIN_PASSWORD' -AsPlainText -Force)[0]) -Restart
</powershell>
EOF
Run Code Online (Sandbox Code Playgroud)

或者,如果您想使用 SSM,使用新的 Terraform 12/13 语法和最新的架构版本,这里是一个准备好复制和粘贴的片段:


data "aws_directory_service_directory" "my_domain_controller" {
  directory_id = "d-XXXXXXXXXXXXX"
}

resource "aws_ssm_document" "ad-join-domain" {
  name          = "ad-join-domain"
  document_type = "Command"
  content = jsonencode(
    {
      "schemaVersion" = "2.2"
      "description"   = "aws:domainJoin"
      "mainSteps" = [
        {
          "action" = "aws:domainJoin",
          "name"   = "domainJoin",
          "inputs" = {
            "directoryId" : data.aws_directory_service_directory.my_domain_controller.id,
            "directoryName" : data.aws_directory_service_directory.my_domain_controller.name
            "dnsIpAddresses" : sort(data.aws_directory_service_directory.my_domain_controller.dns_ip_addresses)
          }
        }
      ]
    }
  )
}

resource "aws_ssm_association" "windows_server" {
  name = aws_ssm_document.ad-join-domain.name
  targets {
    key    = "InstanceIds"
    values = ["i-XXXXXXXXXXXX"]
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 3

正如评论中提到的,可重现的示例将提高任何人提供帮助的能力:)

我假设 terraform 0.12 正在使用中。

aws_directory_service_directory.ad.dns_ip_addresses 不是一个列表,而是一个集合。从概念上讲,这意味着它是无序的。结果,像这样访问它:

sort(aws_directory_service_directory.ad.dns_ip_addresses)[0]
Run Code Online (Sandbox Code Playgroud)

排序会对它进行排序并允许您使用索引来访问它。以下问题解释了这一点,尽管是关于尝试详细使用element访问https://github.com/hashicorp/terraform/issues/22392

该资源的文档称其为一个列表,但实际上似乎不正确:https ://www.terraform.io/docs/providers/aws/r/directory_service_directory.html