Windows CloudFormation Script, MetaData commands are not running - windows

Below is my CloudFormation template for creating a windows EC2 instance with Java and Tomcat installed on it. However, the nothing from the MetaData is being executed. I login to the created EC2 instance, and none of the specified folders in the metadata can be found. What is my CloudFormation script missing?
Thank you
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Script to create Windows AMI",
"Metadata": {
"AWS::CloudFormation::Designer": {
"94153bdc-589b-4aa8-b859-5e84a1051a50": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 280,
"y": 110
},
"z": 1,
"embeds": []
}
}
},
"Parameters": {},
"Rules": {},
"Mappings": {},
"Resources": {
"JavaTomcatEC2Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-06b19063",
"InstanceType": "t2.micro",
"KeyName": "WindowsTest"
},
"Metadata": {
"AWS::CloudFormation::Init": {
"configSets": {
"config": [
"setup"
]
},
"setup": {
"Install-Java-Tomcat-set-env-variables-paths": {
"files": {
"c:\\cfn\\modules\\jdk-8u151-windows-x64.exe": {
"source": "https://s3.amazonaws.com/windows-ami-software/jdk-8u151-windows-x64.exe"
},
"c:\\cfn\\modules\\apache-tomcat-8.5.23.exe": {
"source": "https://s3.amazonaws.com/windows-ami-software/apache-tomcat-8.5.23.exe"
},
"c:\\cfn\\scripts\\Install-Java-JDK.ps1": {
"content": {
"Fn::Join": [
"",
[
"Set-Location C:\\cfn\\modules;",
".\\jdk-8u151-windows-x64.exe /s ADDLOCAL=\"ToolsFeature,SourceFeature,PublicjreFeature\"",
"\n"
]
]
}
},
"c:\\cfn\\scripts\\Install-Tomcat8.ps1": {
"content": {
"Fn::Join": [
"",
[
"Set-Location C:\\cfn\\modules;",
".\\apache-tomcat-8.5.23.exe /S",
"\n"
]
]
}
},
"c:\\cfn\\scripts\\Set-Java-Tomcat8-Paths-Homes.ps1": {
"content": {
"Fn::Join": [
"",
[
"$oldPath=(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment' -Name PATH).Path;",
"$addedFolder = 'C:\\Program Files\\Java\\jdk1.8.0_151\\bin; C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\bin';",
"$newPath = $oldPath +';'+$addedFolder;",
"Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment' -Name PATH -Value $newPath ;",
"[Environment]::SetEnvironmentVariable('CATALINA_HOME', 'C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\', 'Machine');",
"[Environment]::SetEnvironmentVariable('JAVA_HOME', 'C:\\Program Files\\Java\\jdk1.8.0_151\\', 'Machine');",
"Restart-Computer -Force;",
"\n"
]
]
}
},
"c:\\cfn\\scripts\\Install-Tomcat8-Service.ps1": {
"content": {
"Fn::Join": [
"",
[
"Set-Location 'C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\bin';",
".\\service.bat install;",
"Set-Service Tomcat8 -StartupType Automatic;",
"Start-Service Tomcat8;",
"\n"
]
]
}
}
},
"commands": {
"a-Install-Java-JDK": {
"command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Install-Java-JDK.ps1",
"waitAfterCompletion": "30"
},
"b-Install-Tomcat8": {
"command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Install-Tomcat8.ps1",
"waitAfterCompletion": "30"
},
"c-Set-Java-Tomcat8-Paths-Homes": {
"command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Set-Java-Tomcat8-Paths-Homes.ps1",
"waitAfterCompletion": "forever"
},
"d-Install-Tomcat8-Service": {
"command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Install-Tomcat8-Service.ps1",
"waitAfterCompletion": "30"
}
}
}
}
},
"AWS::CloudFormation::Designer": {
"id": "94153bdc-589b-4aa8-b859-5e84a1051a50"
}
}
}
}
}

There are 2 things you need to check:
Check if those scripts are getting created on location C:\cfn\scripts
--IF not then check where is the issue
If these scripts are created there, then call separately the step "commands" in configSets (line no. 33-34). I suspect that is the problem where the actual scripts are not getting called.

Instead of using "setup" block, try something like this. This is how I have been using.
"Metadata": {
"AWS::CloudFormation::Init": {
"config": {
"files": {
"c:\\cfn\\modules\\jdk-8u151-windows-x64.exe": {
"source": "https://s3.amazonaws.com/windows-ami-software/jdk-8u151-windows-x64.exe"
},
"c:\\cfn\\modules\\apache-tomcat-8.5.23.exe": {
"source": "https://s3.amazonaws.com/windows-ami-software/apache-tomcat-8.5.23.exe"
},
"c:\\cfn\\scripts\\Install-Java-JDK.ps1": {
"content": {
"Fn::Join": [
"",
[
"Set-Location C:\\cfn\\modules;",
".\\jdk-8u151-windows-x64.exe /s ADDLOCAL=\"ToolsFeature,SourceFeature,PublicjreFeature\"",
"\n"
]
]
}
},
"c:\\cfn\\scripts\\Install-Tomcat8.ps1": {
"content": {
"Fn::Join": [
"",
[
"Set-Location C:\\cfn\\modules;",
".\\apache-tomcat-8.5.23.exe /S",
"\n"
]
]
}
},
"c:\\cfn\\scripts\\Set-Java-Tomcat8-Paths-Homes.ps1": {
"content": {
"Fn::Join": [
"",
[
"$oldPath=(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment' -Name PATH).Path;",
"$addedFolder = 'C:\\Program Files\\Java\\jdk1.8.0_151\\bin; C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\bin';",
"$newPath = $oldPath +';'+$addedFolder;",
"Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment' -Name PATH -Value $newPath ;",
"[Environment]::SetEnvironmentVariable('CATALINA_HOME', 'C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\', 'Machine');",
"[Environment]::SetEnvironmentVariable('JAVA_HOME', 'C:\\Program Files\\Java\\jdk1.8.0_151\\', 'Machine');",
"Restart-Computer -Force;",
"\n"
]
]
}
},
"c:\\cfn\\scripts\\Install-Tomcat8-Service.ps1": {
"content": {
"Fn::Join": [
"",
[
"Set-Location 'C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\bin';",
".\\service.bat install;",
"Set-Service Tomcat8 -StartupType Automatic;",
"Start-Service Tomcat8;",
"\n"
]
]
}
}
},
"commands": {
"a-Install-Java-JDK": {
"command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Install-Java-JDK.ps1",
"waitAfterCompletion": "30"
},
"b-Install-Tomcat8": {
"command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Install-Tomcat8.ps1",
"waitAfterCompletion": "30"
},
"c-Set-Java-Tomcat8-Paths-Homes": {
"command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Set-Java-Tomcat8-Paths-Homes.ps1",
"waitAfterCompletion": "forever"
},
"d-Install-Tomcat8-Service": {
"command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Install-Tomcat8-Service.ps1",
"waitAfterCompletion": "30"
}
}
}
}
}

Super old... but anywho!
cfn-init is never called. Typically this will be done once via UserData
UserData:
Fn::Base64:
!Sub |
<PowerShell>
cfn-init.exe -v -s ${AWS::StackName} -r <resourceref> --configsets MyConfigSet --region ${AWS::Region}
</PowerShell>
Then within your init you'd also configure the cfn-hup service to monitor a couple configuration files.
AWS::CloudFormation::Init:
configSets:
MyConfigSet:
- configureCfn
configureCfn:
files:
c:\\cfn\\cfn-hup.conf:
content: !Sub |
[main]
stack=${AWS::StackName}
region=${AWS::Region}
c:\\cfn\\hooks.d\\cfn-auto-reloader.conf:
content: !Sub |
[cfn-auto-reloader-hook]
triggers=post.update
path=Resources.UiPathRobot.Metadata.AWS::CloudFormation::Init
action=cfn-init.exe -v -s ${AWS::StackName} -r <resourceref> --configsets MyConfigSet --region ${AWS::Region}
services:
windows:
cfn-hup:
enabled: true
ensureRunning: true
files:
- c:\cfn\cfn-hup.conf
- c:\cfn\hook.d\cfn-auto-reloader.conf
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-windows-stacks-bootstrapping.html

Related

How to launch Windows Terminal with Multiple Tabs?

I am attempting to use startupActions to launch a second tab when Windows Terminal launches with no luck.
My default shell is WSL, so I have the following in my settings.json:
"startupActions": "; new-tab -p PowerShell",
I've tried it without the semi-colon and without the -p flag as well.
Here is the settings.json minus the color schemes:
{
"$help": "https://aka.ms/terminal-documentation",
"$schema": "https://aka.ms/terminal-profiles-schema",
"actions":
[
{
"command":
{
"action": "copy",
"singleLine": false
},
"keys": "ctrl+c"
},
{
"command": "paste",
"keys": "ctrl+v"
},
{
"command": "find",
"keys": "ctrl+shift+f"
},
{
"command":
{
"action": "splitPane",
"split": "auto",
"splitMode": "duplicate"
},
"keys": "alt+shift+d"
}
],
"centerOnLaunch": true,
"copyFormatting": "none",
"copyOnSelect": false,
"defaultProfile": "{2c4de342-38b7-51cf-b940-2309a097f518}",
"initialCols": 98,
"initialRows": 24,
"showTerminalTitleInTitlebar": false,
"startupActions": "; new-tab -p PowerShell",
"useAcrylicInTabRow": true,
"profiles":
{
"defaults":
{
"colorScheme": "Dracula",
"cursorShape": "filledBox",
"elevate": true,
"font":
{
"face": "MesloLGS NF",
"size": 12
},
"startingDirectory": null
},
"list":
[
{
"antialiasingMode": "cleartype",
"experimental.retroTerminalEffect": false,
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"hidden": false,
"name": "Command Prompt",
"opacity": 75,
"useAcrylic": true
},
{
"guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}",
"hidden": true,
"name": "Azure Cloud Shell",
"opacity": 75,
"source": "Windows.Terminal.Azure",
"useAcrylic": true
},
{
"antialiasingMode": "cleartype",
"experimental.retroTerminalEffect": false,
"font":
{
"size": 12
},
"guid": "{2c4de342-38b7-51cf-b940-2309a097f518}",
"hidden": false,
"name": "Ubuntu",
"opacity": 75,
"scrollbarState": "visible",
"source": "Windows.Terminal.Wsl",
"startingDirectory": "\\\\wsl$\\Ubuntu\\home\\steve",
"suppressApplicationTitle": true,
"tabColor": "#BD93F9",
"tabTitle": "Ubuntu 20.04",
"useAcrylic": true
},
{
"antialiasingMode": "cleartype",
"experimental.retroTerminalEffect": false,
"font":
{
"face": "Fira Code Retina"
},
"guid": "{574e775e-4f2a-5b96-ac1e-a2962a402336}",
"hidden": false,
"name": "PowerShell",
"opacity": 75,
"source": "Windows.Terminal.PowershellCore",
"tabColor": "#6272A4",
"useAcrylic": true
}
]
}
}
"elevate": true is your culprit here. You can't have mixed-elevation of tabs in the same window. Admin and non-admin windows need to stay separate. So when you launch those startupActions, the Terminal automatically creates a new admin window to host the powershell tab (which you've set to always run as admin).
Removing that setting from your powershell profile should work.

What is "Exported Binaries" in yarn info

I am trying to understand the output of
yarn info ts-node --json
{
"value": "ts-node#npm:8.5.4",
"children": {
"Instances": 1,
"Version": "8.5.4",
"Exported Binaries": [
"ts-node",
"ts-script"
],
"Dependencies": [
{
"descriptor": "arg#npm:^4.1.0",
"locator": "arg#npm:4.1.3"
},
{
"descriptor": "diff#npm:^4.0.1",
"locator": "diff#npm:4.0.2"
},
{
"descriptor": "make-error#npm:^1.1.1",
"locator": "make-error#npm:1.3.6"
},
{
"descriptor": "source-map-support#npm:^0.5.6",
"locator": "source-map-support#npm:0.5.21"
},
{
"descriptor": "yn#npm:^3.0.0",
"locator": "yn#npm:3.1.1"
}
]
}
}
So far I understand ts-node version 8.5.4 is installed
But what does "Exported Binaries" signify? I thought it would mean direct dependency but I don't have ts-script in my package.json.

Heroku: There was an issue setting up your app environment. Name is invalid

When I try to use this app.json:
{
"stack": "heroku-18",
"repository": "https://github.com/OpenHumans/oh-data-source-template",
"logo": "https://avatars.githubusercontent.com/u/3341265?s=280&v=4",
"scripts": {
"postdeploy": "python manage.py init_proj_config"
},
"env": {
"SECRET_KEY": {
"description": "This is set for you and is used to encrypt data.",
"generator": "secret"
},
"OH_CLIENT_ID": {
"description": "See http://openhumans.org/direct-sharing/projects/manage",
"value": ""
},
"OH_CLIENT_SECRET": {
"description": "See http://openhumans.org/direct-sharing/projects/manage",
"value": ""
},
"OH_ACTIVITY_PAGE": {
"description": "See http://openhumans.org/direct-sharing/projects/manage",
"value": ""
},
"APP_BASE_URL ": {
"description": "e.g. https://your-app-name.herokuapp.com - no trailing slash!",
"value": "https://your-app-name.herokuapp.com"
},
"DEBUG": {
"description": "Displays detailed error info for web requests. Set False in production.",
"value": "false"
},
"HEROKU_APP": {
"description": "If true, ALLOWED_HOSTS is set to all.",
"value": "true"
}
},
"addons": [
"coralogix:free-30mbday",
"heroku-redis:hobby-dev",
{
"plan": "heroku-postgresql",
"options": {
"version": "9.5"
}
}
]
}
to deploy from:
https://dashboard.heroku.com/new?template=https%3A%2F%2Fgithub.com%2Fmikepsinn%2Foh-quantimodo-source
I get the error no matter what I set the name to:
I've tried adding the optional name field to the app.json but that doesn't help either.

join multiple arrays in complex data structure with jmespath

I'm trying to transform NFS exports, described in complex data structure, to config option accepted by nfs-server daemon which later be used in ansible.
I have:
nfs_exports:
- path: /export/home
state: present
options:
- clients: "192.168.0.0/24"
permissions:
- "rw"
- "sync"
- "no_root_squash"
- "fsid=0"
- path: /export/public
state: present
options:
- clients: "192.168.0.0/24"
permissions:
- "rw"
- "sync"
- "root_squash"
- "fsid=0"
- clients: "*"
permissions:
- "ro"
- "async"
- "all_squash"
- "fsid=1"
which must become:
[
{
"options": "192.168.0.0/24(rw,sync,no_root_squash,fsid=0)",
"path": "/export/home",
"state": "present"
},
{
"options": "192.168.0.0/24(rw,sync,root_squash,fsid=0) *(ro,async,all_squash,fsid=1)",
"path": "/export/public",
"state": "present"
}
]
So far I was able, using {{ nfs_exports | json_query(query) }}
query: "[].{path:path,state:state,options:options.join(` `,[].join(``,[clients,`(`,join(`,`,permissions),`)`]))}"
get
{
"options": "192.168.0.0/24(rw,sync,no_root_squash,fsid=0)",
"path": "/export/home",
"state": "present"
},
{
"options": "192.168.0.0/24(rw,sync,root_squash,fsid=0)*(ro,async,all_squash,fsid=1)",
"path": "/export/public",
"state": "present"
}
It's probably simple but I can't get pass that last options join, space ' ' gets removed.
So if someone knows the correct query additional explanation will be much appreciated.
Given the query:
[].{ path: path, state: state, options: join(' ', options[].join('', [clients, '(', join(',', permissions), ')'])) }
On the JSON
{
"nfs_exports": [
{
"path": "/export/home",
"state": "present",
"options": [
{
"clients": "192.168.0.0/24",
"permissions": [
"rw",
"sync",
"no_root_squash",
"fsid=0"
]
}
]
},
{
"path": "/export/public",
"state": "present",
"options": [
{
"clients": "192.168.0.0/24",
"permissions": [
"rw",
"sync",
"root_squash",
"fsid=0"
]
},
{
"clients": "*",
"permissions": [
"ro",
"async",
"all_squash",
"fsid=1"
]
}
]
}
]
}
It would give you your expected output:
[
{
"path": "/export/home",
"state": "present",
"options": "192.168.0.0/24(rw,sync,no_root_squash,fsid=0)"
},
{
"path": "/export/public",
"state": "present",
"options": "192.168.0.0/24(rw,sync,root_squash,fsid=0) *(ro,async,all_squash,fsid=1)"
}
]
Please mind: the string litteral `` wont work on a space character string, because, as pointed in the documentation, it will be parsed as JSON:
A literal expression is an expression that allows arbitrary JSON objects to be specified
Source: https://jmespath.org/specification.html#literal-expressions
This is quite easy when you get to the point of:
[].{ path: path, state: state, options: options[].join('', [clients, '(', join(',', permissions), ')']) }
Which is something you seems to have achived, that gives
[
{
"path": "/export/home",
"state": "present",
"options": [
"192.168.0.0/24(rw,sync,no_root_squash,fsid=0)"
]
},
{
"path": "/export/public",
"state": "present",
"options": [
"192.168.0.0/24(rw,sync,root_squash,fsid=0)",
"*(ro,async,all_squash,fsid=1)"
]
}
]
Because you are just left with joining the whole array in options with a space as glue character.

How to add Custom Script Extension to Azure VM using Ansible

Following advice on https://superuser.com/questions/1210215/how-to-bootstrap-windows-hosts-with-remote-powershell-for-use-with-ansible I am trying to add Custom Script extension to existing VM.
Below is my playbook
- name: Create VM playbook
hosts: localhost
connection: local
tasks:
- name: Custom Script Extension
azure_rm_deployment:
state: present
location: 'uk west'
resource_group_name: 'AnsibleRG'
template: "{{ lookup('file', '/etc/ansible/playbooks/extension.json') | from_json }}"
deployment_mode: incremental
This is extension.json
{
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.4",
"settings": {
"fileUris": [
"https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
],
"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File ConfigureRemotingForAnsible.ps1"
}
}
When I run the playbook I get following error on azure
The request content was invalid and could not be deserialized: 'Could
not find member 'publisher' on object of type 'Template'. Path
'properties.template.publisher', line 1, position 64.'.
Can anyone please point me in right direction?
Thanks
You still need to provide a valid template
You need to provide proper type for the resource, extensions isnt a proper type
Your name has to include the vm name, as this is how the template supposed to figure out which vm apply this extension to.
Example:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vmName": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "[concat(parameters('vmName'),'/ConfigureRemotingForAnsible')]",
"apiVersion": "2015-06-15",
"location": "[resourceGroup().location]",
"properties": {
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.8",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": [
"https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
],
"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File ConfigureRemotingForAnsible.ps1"
}
}
}
]
}

Resources