首页 文章

在AWS上使用打包程序和ansible创建Windows AMI

提问于
浏览
5

我想创建一个带有打包器和ansible的aws windows AMI .

我已经尝试了很多配置,但我仍然存在与实例连接的问题 .

这是我的包装工conf:

{
  "builders": [{
    "type": "amazon-ebs",
    "access_key": "{{user `aws_access_key`}}",
    "secret_key": "{{user `aws_secret_key`}}",
    "region": "eu-west-1",
    "source_ami": "ami-58a1a73e",
    "instance_type": "m3.medium",
    "ami_name": "aaa-windows-ami {{timestamp}}",
    "user_data_file":"./test.ps",
    "communicator": "winrm",
    "winrm_username": "Administrator",
    "winrm_use_ssl": true,
    "winrm_insecure": true
  }],

  "provisioners": [
    {
      "type": "ansible",
      "playbook_file": "./playbook.yml",
      "extra_arguments": [
        "--extra-vars", "ansible_user=Administrator ansible_connection=winrm ansible_ssh_port=5986 ansible_winrm_server_cert_validation=ignore ansible_shell_type=powershell ansible_shell_executable=None"
      ]
    },
    {
      "type": "powershell",
      "script": "./init.ps1"
    }
  ]
}

用户数据脚本正在AWS实例上激活winrm .

<powershell>

write-output "Running User Data Script"
write-host "(host) Running User Data Script"

Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore

# Don't set this before Set-ExecutionPolicy as it throws an error
$ErrorActionPreference = "stop"

# Remove HTTP listener
Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse

Set-Item WSMan:\localhost\MaxTimeoutms 1800000
Set-Item WSMan:\localhost\Service\Auth\Basic $true

$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer"
New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force

# WinRM
write-output "Setting up WinRM"
write-host "(host) setting up WinRM"

cmd.exe /c winrm quickconfig -q
cmd.exe /c winrm set "winrm/config" '@{MaxTimeoutms="1800000"}'
cmd.exe /c winrm set "winrm/config/winrs" '@{MaxMemoryPerShellMB="1024"}'
cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}'
cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}"
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
cmd.exe /c netsh firewall add portopening TCP 5986 "Port 5986"
cmd.exe /c net stop winrm
cmd.exe /c sc config winrm start= auto
cmd.exe /c net start winrm

</powershell>

错误是 .

==> amazon-ebs: Provisioning with Ansible...
    amazon-ebs:
    amazon-ebs: PLAY [all] *********************************************************************
    amazon-ebs:
    amazon-ebs: TASK [setup] *******************************************************************
    amazon-ebs: fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "ssl: auth method ssl requires a password", "unreachable": true}
    amazon-ebs:     to retry, use: --limit @/home/elhostis/repo/vagrant/playbook.retry
    amazon-ebs:
    amazon-ebs: PLAY RECAP *********************************************************************
    amazon-ebs: default                    : ok=0    changed=0    unreachable=1    failed=0
    amazon-ebs:
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: No volumes to clean up, skipping
==> amazon-ebs: Deleting temporary security group...
==> amazon-ebs: Deleting temporary keypair...

我还尝试使用已知的用户名/密码手动创建AMI . 然后,我已经使用这些凭据配置了ansible,但是我有这个错误 .

==> amazon-ebs: Timeout waiting for password.
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: No volumes to clean up, skipping
==> amazon-ebs: Deleting temporary security group...
==> amazon-ebs: Deleting temporary keypair...
Build 'amazon-ebs' errored: Timeout waiting for password.

有人有这样做的例子吗?

非常感谢 .

埃里克

2 回答

  • -1

    您需要按照文档中的说明使用ansible provisioner with WinRM .

    这是运行Windows 2016 Server Base的工作示例:

    {
      "builders": [
      {
        "type": "amazon-ebs",
        "region": "eu-west-1",
        "instance_type": "m3.medium",
        "source_ami": "ami-0983b56f",
        "ami_name": "packer-demo-{{timestamp}}",
        "user_data_file": "windows-userdata.txt",
        "communicator": "winrm",
        "winrm_username": "Administrator"
      }],
      "provisioners": [
      {
          "type":  "ansible",
          "playbook_file": "./win-playbook.yml",
          "extra_arguments": [
            "--connection", "packer", "-vvv",
            "--extra-vars", "ansible_shell_type=powershell ansible_shell_executable=None"
          ]
      }]
    }
    

    windows-userdata.txt

    <powershell>
    winrm quickconfig -q
    winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="300"}'
    winrm set winrm/config '@{MaxTimeoutms="1800000"}'
    winrm set winrm/config/service '@{AllowUnencrypted="true"}'
    winrm set winrm/config/service/auth '@{Basic="true"}'
    
    netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow
    netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow
    
    net stop winrm
    sc config winrm start=auto
    net start winrm
    
    Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope LocalMachine
    </powershell>
    

    win-playbook.yml

    ---
    
    - hosts: all
    
      tasks:
        - win_ping:
          #- ping:
    

    connection_plugins/packer.py

    from __future__ import (absolute_import, division, print_function)
    __metaclass__ = type
    
    from ansible.plugins.connection.ssh import Connection as SSHConnection
    
    class Connection(SSHConnection):
        ''' ssh based connections for powershell via packer'''
    
        transport = 'packer'
        has_pipelining = True
        become_methods = []
        allow_executable = False
        module_implementation_preferences = ('.ps1', '')
    
        def __init__(self, *args, **kwargs):
            super(Connection, self).__init__(*args, **kwargs)
    

    Unfortunatley似乎有最新的(2.3.0)版本Ansible和Packer出现问题,请参阅#4904

  • 7

    我找不到解决方案 . 所以,我不在我的堆栈中使用packer . 我只使用ansible . 这是其他人的代码示例 .

    #
    # First, create a new instance
    #
    - hosts: localhost
      tasks:
        # Create a new instance with an AMI
        - name: Create a new instance
          ec2:
            aws_access_key: "xxx"
            aws_secret_key: "xxx"
            region: "xxx"
            key_name: "xxx"
            instance_type: "t2.small"
            image: "xxx"
            assign_public_ip: yes
            wait: yes
            count: 1
          register: ec2_created
        # Wait a few minutes for windows starting
        - name: Wait for windows is starting
          pause:
            minutes: 5
        # Subscribe the new instance to ansible
        - name: Subscribe host to Ansible
          add_host:
            name: "{{ec2_created.instances[0].dns_name}}"
            groups: win
            ansible_ssh_pass: "xxx"
          no_log: True
    
    #
    # Then, provision the instance
    #
    - hosts: win
      roles:
        - xxx
    
    #
    # Finally, create a new AMI with the instance
    # and destroy it
    #
    - hosts: localhost
      tasks:
        - name: Create AMI
          ec2_ami:
            aws_access_key: "xxx"
            aws_secret_key: "xxx"
            region: "xxx"
            instance_id: "{{ec2_created.instance_ids[0]}}"
            wait: yes
            name: "xxx"
          register: ami_created
    
        - name: Destroy instance
          ec2:
            aws_access_key: "xxx"
            aws_secret_key: "xxx"
            region: "xxx"
            state: 'absent'
            instance_ids: "{{ec2_created.instance_ids[0]}}"
    

相关问题