Cannot create elastic beanstalk with multiple IIS applications - amazon-web-services

I am trying to migrate a production web server to AWS, the server is windows based IIS with multiple applications defined under 1 website. I have tried both Elastic Beanstalk and Cloud formation. I would prefer to elastic beanstalk, but I would be happy with anything that has auto scaling and a easy deployment routine.
I have created a sample website with one child application, it works fine locally. I tried to edit the default AMI for elastic beanstalk to add the extra application and deploy to it. When I tried to redeploy the application with the new AMI, it failed finish the deployment it failed with the following error.
[Instance: i-3f13bc11 Module: AWSEBAutoScalingGroup ConfigSet:
Infra-WriteRuntimeConfig, Infra-WriteApplication1,
Infra-WriteApplication2, Infra-EmbeddedPreBuild, Hook-PreAppDeploy,
Hook-EnactAppDeploy, Infra-EmbeddedPostBuild, Hook-PostAppDeploy]
Command failed on instance. Return code: 1 Output: null.
I did try to use the cloud-formation template that comes with the visual studio, it did not work either, it failed with a very similar error message.

The best way to do this is to use CloudFormation to create an auto scale group. In the LaunchConfiguration type you can add your files from S3 and instruct IIS to install the apps. For example:
"WebAsSpotLaunchConfiguration" : {
"Type" : "AWS::AutoScaling::LaunchConfiguration",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"sources" : {
"C:\\inetpub\\wwwroot" : {
"Fn::Join" : [
"/",
[
"http://s3.amazonaws.com",
{
"Ref" : "DeployS3Bucket"
},
{
"Ref" : "DeployWebS3Key"
}
]
]
}
},
"commands" : {
"1-add-app-1" : {
"command" : "C:\\Windows\\System32\\inetsrv\\appcmd add app /site.name:MySite /path:/app1 /physicalPath:C:\inetpub\mysite\app1",
"waitAfterCompletion" : "0"
},
"2-add-app-2" : {
"command" : "C:\\Windows\\System32\\inetsrv\\appcmd add app /site.name:MySite /path:/app2 /physicalPath:C:\inetpub\mysite\app2",
"waitAfterCompletion" : "0"
}
}
}
},
I realize that if you don't already know CloudFormation, this may take some time to setup. But it's worth the investment in my opinion.

Related

startup scripts on Google cloud platform using Packer

Im using hashicorp's Packer to create machine images for the google cloud (AMI for Amazon). I want every instance to run a script once the instance is created on the cloud. As i understand from the Packer docs, i could use the startup_script_file to do this. Now i got this working but it seems that the script is only runned once, on image creation resulting in the same output on every running instance. How can i trigger this script only on instance creation such that i can have different output for every instance?
packer config:
{
"builders": [{
"type": "googlecompute",
"project_id": "project-id",
"source_image": "debian-9-stretch-v20200805",
"ssh_username": "name",
"zone": "europe-west4-a",
"account_file": "secret-account-file.json",
"startup_script_file": "link to file"
}]
}
script:
#!/bin/bash
echo $((1 + RANDOM % 100)) > test.log #output of this remains the same on every created instance.

error launching simple web app in docker container on AWS Elastic Beanstalk

That is what I get when I follow the instructions at the official Docker tutorial here: tutorial link
I uploaded my Dockerrun.aws.json file and followed all other instructions.
The logs show nothing even when I click Request:
If anyone has a clue as to what I need to do, ie. why would not having a default VPC even matter here? I have only used my AWS account to set up Linux Machine EC2 instances for a Deep Learning nanodegree at Udacity in the past (briefly tried to set up a VPC just for practice but am sure I deleted/terminated everything when I found out that is not included in the free tier).
The author of the official tutorial forgot to add that you have to add the tag to the image name in the Dockerrun.aws.json file per below in gedit or other editor where :firsttry is the tag:
{
"AWSEBDockerrunVersion": "1",
"Image": {
"Name": "hockeymonkey96/catnip:firsttry",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "5000"
}
],
"Logging": "/var/log/nginx"
}
It works:

Use user data in cloudformation for 2016 windows ami

I am trying to add userdate to run some custom script when I create a windows ec2 instance using cloudformation. (Windows 2016)
"UserData" : {
"Fn::Base64" : {
"Fn::Join" : [
"",
[
"<powershell> \n",
"C:\\ProgramData\\Amazon\\EC2-Windows\\Launch\\Scripts\\InitializeI‌​nstance.ps1 \n",
"C:\\ProgramData\\Amazon\\EC2-Windows\\Launch\\Scripts\\create_folder.ps1 \n",
"New-Item -Path c:\\test3 -ItemType directory",
"</powershell>"
]
]
}
},
the above script does not seems to be working.
Basically I need to run some custom script (which I already added in my base image) and some powershell command.
By default the UserData section is not executed in 2016 Windows AMI.
You have to do the following steps manually;
Log-in to the instance. Open powershell terminal.
Go to the directory C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts.
Run
InitializeInstance.ps -Schedule command.
After next start-up, the user-data section will be executed.
I believe now you encounter another issue that you can't manually login to the instance.
Then what you can do is create your own AMI by customizing Windows 2016 AMI with adding the following steps also.
Reference: https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html

Custom Opsworks layer fails while deploying new Postgresql server

I'm following this guide to create a custom Postgresql layer within Opsworks to build a server for my Ruby on Rails app. I'm using this custom JSON as provided in the blog post:
{
"postgresql" : {
"password" : {
"postgres" : "unhackablepassword"
},
"contrib" : {
"packages" : ["postgresql-contrib-9.2"],
"extensions" : ["hstore"]
}
}
}
The following custom cookbooks are used (git://github.com/growthrepublic/cookbooks.git)
postgresql::contrib
postgresql::ruby
postgresql::server
postgresql
The instance setup fails with this error message:
[2014-01-08T20:36:49+00:00] FATAL: Chef::Exceptions::Package: package[postgresql-contrib-9.2] (postgresql::contrib line 24) had an error: Chef::Exceptions::Package: No version specified, and no candidate version available for postgresql-contrib-9.2
I'm new to Chef and Opsworks, does any one have any idea why it's failing?
Thanks!
Francis
I've had success by adding the OS Package: postgresql-server-dev-9.3

How do you pass custom environment variable on Amazon Elastic Beanstalk (AWS EBS)?

The Amazon Elastic Beanstalk blurb says:
Elastic Beanstalk lets you "open the hood" and retain full control ... even pass environment variables through the Elastic Beanstalk console.
http://aws.amazon.com/elasticbeanstalk/
How to pass other environment variables besides the one in the Elastic Beanstalk configuration?
As a heads up to anyone who uses the .ebextensions/*.config way: nowadays you can add, edit and remove environment variables in the Elastic Beanstalk web interface.
The variables are under Configuration → Software Configuration:
Creating the vars in .ebextensions like in Onema's answer still works.
It can even be preferable, e.g. if you will deploy to another environment later and are afraid of forgetting to manually set them, or if you are ok with committing the values to source control. I use a mix of both.
Only 5 values is limiting, or you may want to have a custom environment variable name. You can do this by using the configuration files. Create a directory at the root of your project called
.ebextensions/
Then create a file called environment.config (this file can be called anything but it must have the .config extension) and add the following values
option_settings:
- option_name: CUSTOM_ENV
value: staging
After you deploy your application you will see this new value under
Environment Details -> Edit Configuration -> Container
for more information check the documentation here:
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html#customize-containers-format-options
Update
To prevent committing to your repository values like API keys, secrets and so on, you can put a placeholder value.
option_settings:
- option_name: SOME_API_KEY
value: placeholder-value-change-me
Later you can go to the AWS admin panel (Environment Details -> Edit Configuration -> Container) and update the values there. In my experience these values do not change after subsequent deployments.
Update 2
As #Benjamin stated in his comment, since the new look and feel was rolled out July 18, 2013 it is possible to define any number of environment variables directly from the console:
Configuration > Software Configuration > Environment Properties
In the 2016 Java8 Tomcat8 AMI, ElasticBeanstalk fails to set environment variables from the web configuration. They are really setting jvm -D properties instead.
--
"The following properties are passed into the application as environment variables. Learn more."
This statement is incorrect for the Java Tomcat ami. Amazon does not set these as environment variables. They are set as System properties passed on the command line to Tomcat as a -D property for jvm.
The method in Java to get environment variables is not the same for getting a property.
System.getenv vs System.getProperty
I ssh'd into the box and verified that the environment variable was never set. However, in the tomcat logs I can see the -D property is set.
I've changed my code to check for both locations now as a workaround.
AWS will interpret CloudFormation template strings in your environment variables. You can use this to access information about your EB environment inside your application:
In the AWS web interface the following will be evaluated as the name of your environment (note the back ticks):
`{ "Ref" : "AWSEBEnvironmentName" }`
Or, you can use an .ebextensions/*.config and wrap the CloudFormation template in back ticks (`):
{
"option_settings": [
{
"namespace": "aws:elasticbeanstalk:application:environment",
"option_name": "ENVIRONMENT_NAME",
"value": "`{ \"Ref\" : \"AWSEBEnvironmentName\" }`"
}
]
}
Alternatively, you could use the Elastic Beanstalk CLI to set environment variables.
To set an environment variable: eb setenv FOO=bar
To view the environment variables: eb printenv
Environment Details -> Edit Configuration -> Container
This seems to be the only way to set ENVs with dynamic values in beanstalk. I came up with a workaround that works for my multi-docker setup:
1) Add this to your Dockerfile before building + uploading to your ECS
repository:
CMD eval `cat /tmp/envs/env_file$`; <base image CMD goes here>;
2) In your Dockerrun.aws.json file create a volume:
{
"name": "env-file",
"host": {
"sourcePath": "/var/app/current/envs"
}
}
3) Mount volume to your container
{
"sourceVolume": "env-file",
"containerPath": "/tmp/envs",
"readOnly": true
}
4) In your .ebextensions/options.config file add a container_commands
block like so:
container_commands:
01_create_mount:
command: "mkdir -p envs/"
02_create_env_file:
command: { "Fn::Join" : [ "", [ 'echo "', "export ENVIRONMENT_NAME=" , { "Ref", "RESOURCE" }, ';" > envs/env_file;' ] ] }
5) eb deploy and your ENVS should be available in your docker container
You can add more ENVs by adding more container_commands like:
02_create_env_file_2:
command: { "Fn::Join" : [ "", [ 'echo "', "export ENVIRONMENT_NAME_2=" , { "Ref", "RESOURCE2" }, ';" >> envs/env_file;' \] \] }
Hope this helps!