How to start a program on instance start on AWS EC2 - amazon-web-services

I have a AWS EC2 Windows (2008 R2 instance) which I want to start-stop using command/script from my local machine and schedule as per my usage.
I also want couple of my programs running on the EC2 instance to get start when instance starts. These programs currently are started using a bat file present in the instance.
I did following till now for the same:
1- I have an AWS user created in AWS IAM and using auth_id and key for that user for using EC2 apis and command line utilities.
2- To start and stop instance I'm using command line utilities from EC2 Util.
start ->ec2-start-instances i-instanceID
stop ->ec2-stop-instances i-instanceID
3- To schedule it I've added this to my windows scheduler.
4- Added user data for the instance in the AWS management console. My user data looks like this:
<script>
C:\Services\my_application.lnk
</script>
5- I can see the user data is present in my EC2 instance at C:\ProgramFiles\Amazon\Ec2ConfigServer\Scripts\UserScript
6- In C:\Program Files\Amazon\Ec2ConfigService\Settings\confi.xml the values of Ec2SetPassword and Ec2HandleUserData were changed to enabled and added true was added as well.
I'm facing following issues:
1- The user data scripts does not execute every time the instance is started. I'm not able to figure out why.
2- The changes made in Ec2ConfigService\Settings\confi.xml are getting reverted to the default values when the instance is restarted.
I feel this is common use case, and would like to know the best practices and approach taken for automating EC2 operations.
I also need help in starting programs on my instance- where am I going wrong or missing, what else needs to be done etc?

userdata is only executed the very first time that the instance is created. This is by design.
You've got a couple of options - all of which use your userdata script
Copy the my_application.lnk to the startup folder
Register the application in the registry "run" start key (http://blogs.msdn.com/b/powershell/archive/2006/04/25/how-to-access-or-modify-startup-items-in-the-window-registry.aspx)
Register it with the task scheduler to configure it to execute on startup (http://technet.microsoft.com/en-us/library/bb490996.aspx)

Related

set (guest) metadata from host and update from inside VM

I pass a custom startup script when I instantiate a VM. This startup script can take a while to finish and I want to be able to block (or at least poll) on the host and wait for the VM to get to the end of the startup script before proceeding to next steps.
The official documents recommends using guest attributes for this exact purpose but as far as I can see you can only instantiate them from inside VM. This is fine but ideally I'd like to be able to read a ready=FALSE value from the beginning and then see it changing to TRUE instead of starting with "ready doesnt't exist" error.
Is it possible to provide an initial value for guest attributes when starting a VM?
For normal metadata there's a ?wait_for_change=true that allows a VM to block and react to changes made to the VM from the outside but I'm looking for the opposite.
We use cloud-init in the startup-script to configure some instances. Cloud-init modules run at multiple stages of the boot process, some very early such as bootcmd.
Perhaps you could put a curl command in the bootcmd module to set the desired guest attributes in the metadata?

Add user while instance creation in google cloud

I want to create users in windows server on google cloud during instance creation. Searched in google cloud documentation and other sites but could not find answers. I am aware of startup scripts but those are great when you want to do something every time machine boots up. Please help.
You can use GCP startup script to do it. Please have a look at the documentation Running startup scripts. For example, you can easily add a user John and add him to the group Remote Desktop Users by using metadata:
and, as a result, you'll be able to login via RDP to your VM instance with login John and password fadf24as.FD*.
By default such script will be executed during each start cycle of VM instance:
Compute Engine lets you create and run your own startup scripts on
your virtual machine (VM) instances to perform automated tasks every
time your instance boots up.
To change this default behavior you can add there additional step like creating some folder or file and use them as a flag: if folder or file already exist than rest part of the script should be skipped. In such case PowerShell looks more suitable than cmd, final script could be uploaded from Google Cloud Bucket.

How to pass the details of an AWS instance to a jenkins job, for the job to ssh and execute in the instance

I am trying to move the execution of automated scripts(Jenkins jobs) in my organization from local server to AWS. I have a Jenkins job to bring up an ec2 instance from the snapshot. The instance which I have brought up consists of 5 user profiles, a total of 5 automation jobs can login to the instance and execute their scripts.
My problem is, the instance I'm bringing up will be terminated once the jobs have been executed(Since we execute those scripts around 3 to 4 times in a month). So each time, I bring up an instance , it will have different IP address, which needs to be passed to the other Jenkins jobs, for the jobs to login into the instance and execute the scripts. My questions is as follows.
How to pass the details of the instance to the jenkins , making the process dynamic?
Are there any other ways , by which this problem can be solved(any solution which you might have implemented at your organisation)?
There are two things that you want to configure in your Jenkins in order to pass parameters to your jobs.
Enable "Trigger build remotely" in the Build Triggers. Read more about it here.
Enable "This project is parameterized" and configure your parameters. Read more about it here.
Now you can start your jobs remotely and pass parameters in your URI like so:
http://server/job/myjob/buildWithParameters?token=TOKEN&PARAMETER=Value
this is also explained in the second link.
Then all thats left to do is add the parameter to your command line args for your script. So if you use Execute Shell build step it would look like this:
python /path/to/file/scripit.py --some_arg ${PARAMETER}

How to deativate UFW from outside the VM on Google Cloud Compute Instance

I accidentaly enabled the UFW on my Google Cloud Compute debian instance and unfortunately port 22 is blocked now. I've tried every way to go inside the VM but i can't...
I'm trying to access trhougth the serial port but it's asking me for user and password that was never set.
Does anyone have any idea what can I do?
If I could 'edit' the files on disk, it would be possible to change firewall rules and disable it. Already thought on mounting the VM disk on another instance but Google doesn't allow to "hot detach" it.
Also tried to create another VM from a snapshot of VM disk, but of course, the new instance came with the same problem.
Lots of important files inside and can't go in...
This is the classical example when you close yourself outside of the house with the key inside.
There are several ways to get back inside a virtual machine when the ssh is not currently working in Google Cloud Platform, from my point of view the easiest is to make use of the startup script.
You can use them to run a script as Root when your machine starts, in this way you can basically change the configuration without accessing the virtual machine.
Therefore you can:
simply launch some command in order to deactivate UFW and then access again the machine
if it is not enough and you rally need to access to fix the configuration, you can set up username and password for the root user making use of the startup script and then accessing through the serial console therefore without ssh (basically it is like you had your keyboard directly connected to the hardware). Note as soon you access the instance remove or at least change the password you have just used was visible to the people having access to the project. A safer way is to write down the password in on a private file on a bucket and download it on the instance with the startup script.
Note that you can redirect the output of command to a file and then upload the file to a bucket if you need to debug the script, read the content of a file, understanding what is going on, etc.
The easiest way is to create a startup-script that disables ufw. which gets executed whenever the instance is booted:
Go into your Google Cloud Console. Go to your VM instance and click Edit button.
Scroll down to your "Custom metadata", and add a "startup-script" as key and the following script as value:
#! /bin/bash
/usr/sbin/ufw disable
Click save and reboot your instance.
Delete that startup-script and click Save, so that it won't get executed in future boots.
You can try google serial ports. From then you can enable the ssh
https://cloud.google.com/compute/docs/instances/interacting-with-serial-console
ufw allow ssh

How does ElasticBeanStalk deploy your application version to instances?

I am currently using AWS ElasticBeanStalk and I was curious as to how (as in internally) it knows that when you fire up an instance (or it automatically does with scaling), to unpack the zip I uploaded as a version? Is there some enviroment setting that looks up my zip in my S3 bucket and then unpacks automatically for every instance running in that environment?
If so, could this be used to automate a task such as run an SQL query on boot-up (instance deployment) too? Are these automated tasks changeable or viewable at all?
Thanks
I don't know how beanstalk knows which version to download and unpack, but running a task on start-up is trivial. Check out cloud-init, a tool written by Ubuntu that's now packaged in Amazon Linux. It allows you to pass arbitrary shell scripts into the UserData section of the instance configuration, and those shell scripts will run on startup.
It's a great way to bootstrap instances on startup, which avoids the soul-sucking misery of managing AMIs.
A quick (possibly non-applicable) warning: If you're running a SQL query on a database that lives on the beanstalk AMI, you're pretty much guaranteed to lose your database at some point. Those machines are designed to be entirely transient. Do not put databases on them. See this answer for more details.
Since your goal seems to be to run custom configuration tasks, the answer is yes, there is a way to do that. You can define custom actions in an .ebextensions file packaged with your app. For example, you can configure a command to run every time a new machine is deployed:
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html#linux-commands