Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a Windows AMI with packer and ansible on AWS

I want to create an aws windows AMI with packer and ansible.

I have tried many configuration, but I have still a problem of connection to the instance.

Here is my packer 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"
    }
  ]
}

The User data script is activating winrm on the AWS instance.

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

The error is.

==> 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...

I have also tried to create manually an AMI with a known username/password. Then, I have configured ansible with theses credentials, but I have this error.

==> 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.

Someone have an example to do that ?

Thanks a lot.

Eric

like image 376
elhostis Avatar asked May 05 '17 11:05

elhostis


People also ask

How do I make Windows AMI with Packer?

In brief, Packer will spin up the source AMI, connect to it and then run whatever commands or scripts we've configured in our build template to customize the image. Finally, when all is done, Packer will wrap the whole customized package up into a brand new AMI that will be available from the AWS AMI management page.

Does Packer use Ansible?

The ansible Packer provisioner runs Ansible playbooks. It dynamically creates an Ansible inventory file configured to use SSH, runs an SSH server, executes ansible-playbook , and marshals Ansible plays through the SSH server to the machine being provisioned by Packer.


1 Answers

You need follow the instructions in the documentation for using the ansible provisioner with WinRM.

This is a working example running 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 there seems to be a problem with the latest (2.3.0) version Ansible and Packer, see #4904

like image 92
Rickard von Essen Avatar answered Sep 28 '22 11:09

Rickard von Essen