NET applications, can take several minutes and possibly even hours. His post shows a general technique for using cfn-signal after an instance completes its initialization to trigger other dependent instances which were launched in parallel to begin initialization.
Launching multiple instances simultaneously, and then blocking initialization only when necessary, can significantly reduce total stack creation time.
This post describes a specialization of his technique as it applies to connecting Microsoft Windows Server instances to a domain. Often, a domain controller needs to be set up before an application server can connect to the domain. To reduce stack creation time, you can launch those two servers in parallel, as long as there is a mechanism to block the application server from attempting to join the domain until the domain controller is fully initialized.
Using the DependsOn element in the application server instance is one solution. A faster technique is to use cfn-signal. Of course, in a production environment, you would have two Availability Zones and redundant instances for high availability. There are many variables that affect total stack creation time, including instance types, regions, and other intangibles.
I timed three approaches described later to building the infrastructure shown in the diagram and got the following results using m4. The CloudFormation templates are included below so you can try it yourself. After you deploy the stack in CloudFormation, you can remotely connect to the BastionHost1 instance using the administrator password you specified when you launched the stack.
This CreationPolicy attribute sets a minute timeout. It has code to load a couple of CloudFormation configuration files and a couple of PowerShell scripts on the instance. It also sets a static IP address for the domain controller recommended practiceand renames the instance to DC1.
Then it has commands that install the Active Directory forest and create the domain administrator. None of the commands in the Metadata section will run unless the UserData section of DC1 includes the command to run cfn-init. Before your stack can run cfn-init. Now consider a better way to do this. The WaitHandle is triggered by DC1 when it finishes running all of its initiation logic to install the Active Directory forest.
This allows Server1 to launch simultaneously with DC1, but not connect to the domain until DC1 has created the forest. Now look at the finalize section in the DC1 metadata. It runs cfn-signal. Unfortunately, the syntax of the PowerShell code inside JSON gets a bit tricky with respect to double-quoted strings and newlines. When you develop PowerShell inside CloudFormation, you need to login to the instance and examine the PowerShell results in cfn-init. For more details, see the tip at the end of this section.
The best way to do this is to launch the Server1 instance with an IamInstanceProfile property. One more tip: Remember when I said that your stack needs outbound Internet access before it can run cfn-init. The same is true if your stack uses cfn-signal.Tagging can restrict the control that you have over your instances. In the code editor, on the Parameters tab, choose Template. See the following UserData section examples for Linux and Windows.
You must also attach an instance profile to your EC2 instances. In the Parameters section, enter the appropriate information based on the needs of your environment, including your instance type, EC2 key pair, and AMI.
In the Options section, enter the appropriate information for your stack, and then choose Next. Open the Amazon EC2 console. In the navigation pane, in the Elastic Block Store section, choose Volumes. Last updated: Choose Create Stackand then choose Design template. JSON template:.
You will be billed for the AWS resources used if you create a stack from this template. Ref InstanceType AvailabilityZone:! Ref InstanceProfile KeyName:! Ref InstanceRole. Linux example:. Choose the Create stack icon. For Stack nameenter a name for your stack. Choose Next. Choose Create. Tag the root volume of the instance 1.
Did this article help you? Anything we could improve? Let us know.Connect to AWS with Windows PowerShell
Need more help? Contact AWS Support.The userdata is the user custom content exposed to the guest instance by the currently deployed and running cloud infrastructure. Its purpose is to provide additional data for the instance to customize it as much as you need, if the cloud initialization service does support this feature.
Fortunately, cloudbase-init is able to interpret and use this kind of user specific data in multiple ways. In most of the cases, the thing that indicates of what type is the processed data is usually the first line. The file is executed in a cmd. Execute PowerShell scripts using the desired executable. For finding out more about the system nativeness thing, click here. A bash shell needs to be installed in the system and available in the PATH in order to use this feature.
Python is available by default with the build itself, but also it must be in the system PATH. The following cloud-config directives are supported:. It can be a list of items or only one item, with the following attributes:.
The users are defined as a list. Each element from the list represents a user. Each user can have the the following attributes defined:. The servers and pools are aggregated, servers being the first ones in the list.
On Windows, there is no difference between an NTP pool or server. A command can be defined as a string or as a list of strings, the first one being the executable path. On Windows, the commands are aggregated into a file and executed with cmd. The userdata exit codes can be used to request a reboot: File execution. The reboot is performed at the end of the cloud-config execution after all the directives have been executed. On 32bit OSes, the return value will be the System32 directory, which contains 32bit programs.
On 64bit OSes, the return value may be different, depending on the Python bits and the sysnative parameter. If the Python interpreter is 32bit, the return value will be System32 containing 32bit programs if sysnative is set to False and Sysnative otherwise.
On a WOW case 32bit interpreter on 64bit OSa return value of System32 will point to the physical SysWOW64 directory and a return value of Sysnativewhich is consolidated by the existence of this alias, will point to the real physical System32 directory found on disk.
If the OS is still 64bit and there is no WOW case that means the interpreter is 64bitthe system native concept is out of discussion and each return value will point to the physical location it intends to. Its purpose is to provide the correct system paths by taking into account the Python interpreter bits too, because on a 32bit interpreter version, System32 is not the same with the System32 on a 64bit interpreter.
Also, using a 64bit interpreter, the Sysnative alias will not work, but the sysnative parameter will take care to return SysWOW64 if you explicitly want 32bit applications, by setting it to False. It can be a list of items or only one item, with the following attributes: path - Absolute path on disk where the content should be written. If the hostname is changed, a reboot will be required.
Each user can have the the following attributes defined: name - The username required string. On Linux, the password is a hashed string, whereas on Windows the password is a plaintext string. If the password is not defined, a random password will be set.
If set to True, the user will be disabled.If you've got a moment, please tell us what we did right so we can do more of it. Thanks for letting us know this page needs work. We're sorry we let you down. If you've got a moment, please tell us how we can make the documentation better. When you launch a Windows instance in Amazon EC2, you can pass user data to the instance that can be used to perform automated configuration tasks or run scripts after the instance starts.
Instance user data is treated as opaque data; it is up to the instance to interpret it. For EC2Config or EC2Launch to execute scripts, you must enclose the script within a special tag when you add it to user data.
The tag you use depends on whether the commands run in a Command Prompt window batch commands or use Windows PowerShell. If you specify both a batch script and a Windows PowerShell script, the batch script runs first and the Windows PowerShell script runs next, regardless of the order in which they appear in the instance user data.
An instance profile provides the appropriate AWS credentials required by the user data script to execute the API call. For more information, see Instance Profiles. Specify a batch script using the script tag. Separate the commands using line breaks. For example:. By default, the user data scripts are executed one time when you launch the instance. If you associate an IAM role with your instance, you don't need to specify credentials to the cmdlets, as applications that run on the instance use the role's credentials to access AWS resources for example, Amazon S3 buckets.
Specify a Windows PowerShell script using the powershell tag. If you're using the Amazon EC2 API or a tool that does not perform base64 encoding of the user data, you must encode the user data yourself.
If not, an error is logged about being unable to find script or powershell tags to execute. The following is an example that encodes using Windows PowerShell. You can specify that user data scripts are executed the next time the instance reboots or restarts. Alternatively, you can specify that user data scripts are executed every time the instance reboots or restarts.
Server Fault is a question and answer site for system and network administrators. It only takes a minute to sign up. I have a AWS cloudforamtion - whih build my entire VPC with subnets etc - within this CF builds a windows server - we want to bootstrap this server under user data so it become a domain controller. All our ps1 scripts are hosted on github.
PS1 script which is hosted on git - when i run this script on local server all works OK so it promotes to AD by running local however the pull from git is not working - I have also tried:.
Any ideas please as I have one week try to figure out how i can do this? Left is a command to run the bloody script : i had it working but lost the command during one of the tests. AWS should update their documentation with info regarding this. Sign up to join this community. The best answers are voted up and rise to the top. Home Questions Tags Users Unanswered. Asked 3 years, 11 months ago. Active 3 months ago. Viewed 4k times.
Jenna Shaik Jenna Shaik 11 1 1 silver badge 5 5 bronze badges. Please clarify "not working". What error messages are you seeing? Thank you - rename the computer works from above srcript - what is not working - is not pulling or retriving the powershell script from github - so the windows server does not get promoted to active directory - in terms of erros not much i can see on ec2config logs - does not tell me much about the user data - i cant find anywhere how i can see the errors.
Do you have internet connectivity on the instance public IP address or NATted depending on the subnet? Active Oldest Votes. Bogdan Popescu Bogdan Popescu 1 1 1 bronze badge.
Sign up or log in Sign up using Google. Sign up using Facebook. Sign up using Email and Password. Post as a guest Name. Email Required, but never shown. The Overflow Blog.
Optimizing Joining Windows Server Instances to a Domain with PowerShell in AWS CloudFormation
The Overflow How many jobs can be done at home? Featured on Meta. Community and Moderator guidelines for escalating issues via new response…. Feedback on Q2 Community Roadmap. Related 2. Hot Network Questions. Question feed.
Subscribe to RSS
CloudFormation intrinsic functions have two different forms, the standard form, and a tag abbreviation. The only limitation is that you cannot nest additional functions in the abbreviated tag. For example you cannot import a value inside the abbreviated version. The Fn::Sub syntax has two very different forms.
Above we saw the short form. Only simple parameters or resources can be included inside the string argument. This allows you to reference values from other CloudFormation stacks without having to tediously pass them in as Parameters. Say you have a common CloudFormation template which establishes a Route53 hosted zone for you.
All future CloudFormation stacks can reference an exported value from this stack using the! ImportValue function. Our first template creates a Route53 hosted zone.
Note that the difference between the zone name and the DNS name is the trailing period required for zone names.
Which we append using the Sub short form. These values can be referenced in subsequent CloudFormation stacks using the ImportValue function:. Here you can see a more complex version of the Fn::Sub syntax, where the argument is an array of two elements.
Here the parameter name HostedZoneName is not passed into the template as a parameter, nor is it the name of a resource created elsewhere in this template. It is a temporary parameter that exists only in the scope of this Fn::Sub function. Its value is supplied in the map of the second argument:.Wow, it is amazing how time flies.
Long gone are the days when you would have to sit down, pressing each button and choosing each option to deploy your environment. Cloud computing provides you with a way to interface with the fabric, so that you can script the build of your environment.
The benefits of this are enormous. Firstly, it allows you to standardise all your builds. Secondly, it allows you to have a live as-built document the code is the as-built document. Thirdly, the code is re-useable. Most important of all, since the deployment is now scripted, you can automate it. Guess what the best part is? Once the template has been created, all you will have to do is to load it into AWS CloudFormation, provide a few values and sit back and relax.
AWS CloudFormation will do everything for you from there on! A CloudFormation template starts with a definition of the parameters that will be used. The person running the template lets refer to them as an operator will be asked to provide the values for these parameters.
Next, we will define some mappings.
Mappings allow us to define the values for variables, based on what value was provided for a parameter. The next section in the CloudFormation template is Resources. This defines all resources that will be created. If you have any experience deploying Active Directory Forests, you will know that it is extremely simple to do it using PowerShell scripts.
To ensure our PowerShell scripts are stored securely, we will allow access to it only via a certain role and policy. We will use cf-init to do all the heavy lifting for us, once the EC2 instance has been created.
Below is the metadata that will be used. As you can see, I have first defined the role that cf-init will use to access the S3 bucket.