【问题标题】:How would I dynamically change a windows hostname with Ansible in GCP如何在 GCP 中使用 Ansible 动态更改 Windows 主机名
【发布时间】:2021-10-20 10:52:36
【问题描述】:

情况如下:我们正在使用 ansible 对 GCP 中新部署的虚拟机进行大量更改。其中一项更改是更新主机名。

GCP 要求主机名中的第一个字符必须是字母。所以,假设我们在 GCP 中的主机名是 PC1000-blah-blah。使用 Ansible,我想动态提取该主机名 (PC1000-blah-blah) 并将其更改为 1000-blah-blah,删除“PC”。

现在,我可以使用 ansible.windows.win_hostname 插件逐个 VM 执行此操作:https://docs.ansible.com/ansible/latest/collections/ansible/windows/win_hostname_module.html

但我无法弄清楚如何针对一组 VM 运行我的剧本,它足够聪明,可以查看当前主机名(使用 PC)并在每个 VM 上删除 PC。

感谢任何帮助!

【问题讨论】:

  • 你的策略会失败。即使 Ansible 将主机名更改为 1000-blah-blah,您也会破坏 DNS,并导致 DHCP 错误。 VM 主机名必须符合 RFC 1035。此正则表达式定义允许的主机名:[a-z]([-a-z0-9]*[a-z0-9])?.

标签: windows google-cloud-platform ansible hostname


【解决方案1】:

您可以使用ansible-module-gce-facts 收集有关实例的信息。在 Ansible playbook 中,可以使用 hosts: 127.0.0.1connection:local 运行例如。 gcloudlocal shell 中。

设置hostname 也可以使用metadata 完成。对于 Windows VM,还可以进一步自动化实例(如果设置元数据 hostname 不够):

windows-startup-script-urlwindows-startup-script-cmdwindows-startup-script-batwindows-startup-script-ps1sysprep-specialize-script-urlsysprep-specialize-script-cmdsysprep-specialize-script-batsysprep-specialize-script-ps1

这是一个示例sysprep-specialize-script-ps1instance_setup.ps1... 特别是 function Change-InstanceName 不仅应该在 sys-prep 脚本中,而且应该以 windows-startup-script-ps1 运行,这样安装将始终反映 当前主机名来自元数据:

function Change-InstanceName {
  <#
    .SYNOPSIS
      Changes the machine name for GCE Instance
    .DESCRIPTION
      If metadata server is reachable get the instance name for the machine and
      rename.
  #>

  Write-Log 'Getting hostname from metadata server.'

  if ((Get-CimInstance Win32_BIOS).Manufacturer -cne 'Google') {
    if (-not (Test-Connection -Count 1 metadata.google.internal -ErrorAction SilentlyContinue)) {
      Write-Log 'Not running in a Google Compute Engine VM.' -error
      return
    }
  }

  $count = 1
  do {
    $hostname_parts = (Get-Metadata -property 'hostname') -split '\.'
    if ($hostname_parts.Length -le 1) {
      Write-Log "Waiting for metadata server, attempt $count."
      Start-Sleep -Seconds 1
    }
    if ($count++ -ge 60) {
      Write-Log 'There is likely a problem with the network.' -error
      return
    }
  }
  while ($hostname_parts.Length -le 1)

  $new_hostname = $hostname_parts[0]
  # Change computer name to match GCE hostname.
  # This will take effect after reboot.
  try {
    (Get-WmiObject Win32_ComputerSystem).Rename($new_hostname)
    Write-Log "Renamed from $global:hostname to $new_hostname."
    $global:hostname = $new_hostname
  }
  catch {
    Write-Log 'Unable to change hostname.'
    Write-LogError
  }
}

因此您可能不会使用 ansible 更改主机名 ...但仍然可以编辑元数据,以更改 hostname 并提供 windows sys-prep 或启动脚本 - 然后让这些实例自己应用元数据,例如。 Powershell(然后重新启动以应用新的主机名)。

可以在每个实例上运行 (Get-WmiObject Win32_ComputerSystem).Rename($new_hostname) 和/或删除前导 PC,然后重新启动 - 但仍然建议让脚本获取并应用元数据(即自行管理)。好吧,仅在主机名实际发生更改时才重新启动可能是有意义的(上面的示例是一个 sys-prep 脚本,因此它假定在运行后重新启动/关闭)。

这至少会根据元数据(设置时)为您提供当前主机名:

gcloud compute instances describe instance-1 --zone europe-west3-c --format="value(metadata.items.hostname)"

【讨论】:

  • 嗨,马丁,感谢您的详细回复。我尝试在启动时使用 .ps1 脚本重命名:Rename-Computer -ComputerName $env:COMPUTERNAME -NewName ($env:COMPUTERNAME -replace "pc","") -LocalCredential local\admin 但“重命名计算机”命令不允许输入密码,因此该脚本在启动期间因未经授权而失败。也许还有另一种方法可以在启动时这样做,所以它会丢弃“PC”?
猜你喜欢
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 2020-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
相关资源
最近更新 更多