简体   繁体   中英

Create an AMI with EC2 Launch V2 and make userdata run again after reboot

I'm creating an AMI using Packer, this AMI has EC2 Launch V2 to install in the instance. I want to create instances from this AMI and make sure that the userdata of the instance can run again after I restart the instance. So here is the agent-config.yml file :

version: 1.0
config:
- stage: boot
  tasks:
  - task: extendRootPartition
- stage: preReady
  tasks:
  - task: activateWindows
    inputs:
      activation:
        type: amazon
  - task: setDnsSuffix
    inputs:
      suffixes:
      - $REGION.ec2-utilities.amazonaws.com
  - task: setAdminAccount
    inputs:
      password:
        type: random
  - task: initializeVolume
    inputs:
      initialize: all
  - task: executeScript
    inputs:
    - frequency: always
      type: powershell
      runAs: localSystem
      content: |-
        'C:\tools\UserData.ps1'
  - task: setWallpaper
    inputs:
      path: C:\ProgramData\Amazon\EC2Launch\wallpaper\Ec2Wallpaper.jpg
      attributes:
      - hostName
      - instanceId
      - privateIpAddress
      - publicIpAddress
      - instanceSize
      - availabilityZone
      - architecture
      - memory
      - network
- stage: postReady
  tasks:
  - task: startSsm      

The task that does that for me here is : executeScript and you notice that this task calls a ps1 file : 'C:\tools\UserData.ps1' . Why don't I just call directly the original userdata file from EC2 Launch V2 directory ? Well because this directory is named randomly and it changes at everytime : ( see the random numbers at the end )

C:\Windows\System32\config\systemprofile\AppData\Local\Temp\EC2Launch075546250

So I made this script that I call when I create the AMI :

write-output "Retreiving the User data script ..."
$instanceId=(new-object net.webclient).DownloadString('http://169.254.169.254/latest/meta-data/instance-id')
$UserData_encoded = (Get-EC2InstanceAttribute -InstanceId $instanceId -Attribute userData).UserData 
$content = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($UserData_encoded))
Set-Content C:\tools\Userdata.ps1 $content

So now I have the userdata inside a fixed name path: C:\tools\Userdata.ps1

Except that this doesn't work, because when I create an EC2 instance with this AMI, the script that gets the userdata doesn't run again and I end up with userdata to run after reboot like this:

PS C:\tools> type .\Userdata.ps1
<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

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

cmd.exe /c winrm quickconfig -q
cmd.exe /c winrm quickconfig '-transport:http'
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=HTTP" '@{Port="5985"}'
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
cmd.exe /c netsh firewall add portopening TCP 5985 "Port 5985"
cmd.exe /c net stop winrm
cmd.exe /c sc config winrm start= auto
cmd.exe /c net start winrm

</powershell>

What is the solution to this issue ?

For whatever it's worth, User Data should be in a separate yaml file user-data.yml. Maybe try running it from there and see if you have any better luck?

I found your question here because I'm running into my own User Data issues. I'm using EC2 Image Builder to create a Server 2022 image. The problem is that after the pipeline runs and creates my image, when I use that image on my auto-scaling group the User Data never runs. With EC2 Config you could specify that User Data runs on the next boot, but I'm having a hard time finding the secret sauce to do that here. I may end up borrowing your User Data script to pull user data from the

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM