Create Windows AMI with packer and can be used on AWS
I want to create aws AMI window with packer and maybe.
I tried many settings but I still have the problem of connecting 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 custom script data activates 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>
Mistake.
==> 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 also tried to create manually an AMI with a known username / password. Then I configured theses credentials available, 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.
Does anyone have an example for this?
Many thanks.
Eric
source to share
You need to follow the instructions in the documentation to use the available security tool with WinRM .
This is a working example with Windows 2016 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>
mutual 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)
Undoubtedly the problem is related to the latest version (2.3.0) of Ansible and Packer, see # 4904
source to share
I can't find a solution. So, I am not using a packer on my stack. I only use the truth. Here's some sample code for other people.
#
# 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]}}"
source to share