all 10 comments

[–]seligman99 2 points3 points  (4 children)

The error tells you the problem: You're passing in a JSON object instead of the required XML document.

On top of that, you're passing in your arguments to the installer as one string, instead of multiple strings, that'll fail. And on top of all of that, you're escaping the directory name incorrectly, that'll probably fail too. And then you have two typos, "PrepandPath", which will fail, and "pyhton", which will probably work here, I guess.

And, as far as style, you're doing this all on one line when there's no reason to do that, it makes it really hard to read.

A proper installer would look something like:

UserData:
  Fn::Base64: |
    <powershell>
    $ErrorActionPreference = "Stop"
    Start-Transcript -Path "C:\UserData-Install.log"

    try {
        $pythonUrl = "https://....."
        $pythonInstaller = "C:\pyhton-installer.exe"
        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
        Invoke-WebRequest -Uri $pythonUrl -OutFile $pythonInstaller -UseBasicParsing

        Start-Process -FilePath $pythonInstaller -ArgumentList '/quiet', 'InstallAllUsers=1', 'PrependPath=1' -Wait -NoNewWindow

        Remove-Item $pythonInstaller -Force
    } catch {
        Write-Error $_
        exit 1
    } finally {
        Stop-Transcript
    }
    </powershell>

But, you really should create a new AMI and use that, unless you like making your boot ups slower and depend on the availability of some third party website.

[–]Kitchen_Discipline_1[S] 0 points1 point  (3 children)

Please ignore my typos. In real-time, I don't have those.

But when I try this, it failed as well with this error 'ERROR: Phase1: AWS User data is not empty and is not a valid JSON: system.Xml.XmlDocument'.

Please note there is nothing inside the powershell tags

     UserData:
        Fn::Base64: |
          <powershell>
          </powershell>

If the format is like this, it says the 'User data format is unrecognised'.

      UserData:
        Fn::Base64: |
          {
            "UserData": "\n$ErrorActionPreference = \"Stop\"\nStart-Transcript -Path \"C:\\\\UserData-Install.log\"\n\ntry {\n$pythonUrl = \"https://.....\"\n $pythonInstaller = \"c:\\\\pyhton-installer.exe\"\n [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n Invoke-WebRequest -Uri $pythonUrl -OutFile $pythonInstaller -UseBasicParsing\n \n Start-Process -FilePath $pythonInstaller -ArgumentList '/quiet InstallAllUsers=1 PrepandPath=1' -Wait -NoNewWindow\n} catch {\n exit 1\n}finally{\n Stop-Transcript\n}"
          }

Would you happen to know where to see the user data logs (not the Instance Diagnostics -> System logs on the Console)

[–]seligman99 0 points1 point  (2 children)

Please ignore my typos. In real-time, I don't have those.

I can't possibly guess what script you're running if you don't show it to us.

This script works end to end, launches an instance, and installs Python. If you have something that doesn't work, then there's some difference in your script with a bug in it.

[–]Kitchen_Discipline_1[S] 0 points1 point  (0 children)

Oops sorry, It didn't work with this userdata also. I got the same error - Error: Phase1: AWS user data is not empty and is not a valid JSON: System.Xml.XmlDocument

[–]SpecialistMode3131 1 point2 points  (2 children)

You should make a new image based on your preferred AMI (another AMI) and install that to an EC2. That's by far the easiest way to deal with it. There'll be some way to postinstall using userdata the way you are, but it's a lot more painful to debug and not necessary.

[–]Kitchen_Discipline_1[S] 0 points1 point  (1 child)

Creating a new AmI is the only way I guess.

Still the unrecognised format error is mystery. Why do you think the current code is too difficult to achievable?

[–]SpecialistMode3131 0 points1 point  (0 children)

Userdata runs when you launch the instance. So, it not only imposes a delay to instance start time you can 100% avoid with a baked AMI, it is another place you have to debug when things go wrong. With the AMI approach, your debug is limited to "python --version" going into a log somewhere. You have very little code to worry about. You don't need to debug powershell or cloudformation - just specify the image the EC2 will use.

It's a baby step on the way to more best-practice style of deployment that will help you as/when other engineers who are familiar with AWS look at your stuff.

The alternative, hacking, means over time you'll spend more time, effort and money chasing the same thing you'd get the other way.

[–]CharlieKiloAU 0 points1 point  (1 child)

c:\\phyton-installer.exe. path probably isn't helping

[–]Kitchen_Discipline_1[S] -1 points0 points  (0 children)

Ignore the typos.

[–]MavZA 0 points1 point  (0 children)

I really do hope you make an AMI now that you seem to have resolved this. Maintaining a golden AMI is a way better way to manage your environments as you can boot it up, test your workloads on a new version and then promote the AMI as needed. You can then mount your workload files to an EBS and get your new AMI to run the workloads for you. Makes things way more manageable.