When you launch an instance in Amazon EC2, you have the option of passing user data to the instance that can be used to perform common automated configuration tasks and even run scripts after the instance starts. You can pass two types of user data to Amazon EC2: shell scripts and cloud-init directives.
If you are interested in more complex automation scenarios, consider using AWS CloudFormation and AWS OpsWorks.(中国不支持AWS OpsWorks)
Linux Shell
Scripts entered as user data are executed as the root user, so do not use the sudo command in the script. Remember that any files you create will be owned by root; if you need non-root users to have file access, you should modify the permissions accordingly in the script.
By default, user data and cloud-init directives only run during the first boot cycle when you launch an instance.If you stop an instance, modify the user data, and start the instance, the new user data is not executed automatically.
log file /var/log/cloud-init.log
The following example uses the user-data attribute, executes a shell script to configure DNS when launching an Instance, and then adds a Tag to the Instance:
run-instance.sh
#!/bin/bash run_instance() { # Create an EC2 instance based on the configuration file, execute the shell script when creating, and return the instance id instance_id=$(aws ec2 run-instances --cli-input-json file://instance.json --user-data file://add_dns.sh --query 'Instances[0].[InstanceId]' | grep -o -E "i-\w{17}") echo "InstanceId: $instance_id" # Add tags for EC2 echo "Add tags: Name:$1, Category:$2" aws ec2 create-tags --resources $instance_id --tags Key=Name,Value="$1" Key=Category,Value="$2" } run_instance "test" "test"
EC2 configuration file instance.json
{ "DryRun": false, "ImageId": "ami-4ec31723", "KeyName": "Prod Key Pair", "SecurityGroupIds": [ "sg-06242b63" ], "InstanceType": "m3.large", "Placement": { "AvailabilityZone": "cn-north-1b", "Tenancy": "default" }, "Monitoring": { "Enabled": false }, "SubnetId": "subnet-6166bc16", "DisableApiTermination": true, "InstanceInitiatedShutdownBehavior": "stop", "PrivateIpAddress": "10.184.140.11", "EbsOptimized": false }
Configure DNS Shell script add-dns.sh
#!/bin/bash IFCFG="/etc/sysconfig/network-scripts/ifcfg-eth0" # Replace the sixth line with PEERDNS="no" sed -i '6c PEERDNS="no"' $IFCFG # add DNS sed -i '$a DNS1="10.184.141.11"' $IFCFG sed -i '$a DNS1="10.184.141.12"' $IFCFG systemctl restart network
Windows Script
Userdata is executed when an EC2 Instance is created from an Amazon Windows AMI; if you want to customize an AMI, you need to modify the EC2Launch service or EC2Config service configuration before creating an AMI (using EC2Launch starting from Windows Server 2016, before using EC2Config), and then executing userdata.
EC2Launch is located in the C:\ProgramData\Amazon\EC2-Windows\Launch directory. There are two ways to enable:
- Run C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance -Schedule under PowerShell
- Run Ec2LaunchSettings in the C:\ProgramData\Amazon\EC2-Windows\Launch\Settings directory , check the options to be initialized, and select Shutdown with Sysprep (note that this will shut down)
Ec2ConfigService is located in the C:\Program Files\Amazon\Ec2ConfigService directory, you can run EC2ConfigService Settings from the start menu :
There are also two ways to enable userdata:
- Check User Data in the General tab
- Select Shutdown with Sysprep in the Image tab (this ignores if User Data in the General tab is checked)
Windows supports two scripts, one is cmd and the other is PowerShell, which should be encapsulated with <script></script> and <powershell></powershell> respectively. Such as:
<script>dir > c:\test.log</script>
powershell example 1: modify DNS
<powershell>Set-DnsClientServerAddress -InterfaceAlias "Ethernet 2" -ServerAddresses ("10.184.13.14","10.184.13.15")</powershell>
Powershell example 2: Modify the IP address corresponding to the DNS server domain name
<powershell>
$OldObj = Get-DnsServerResourceRecord -Name "prod-db" -ZoneName "iata.com" -RRType "A"
$NewObj = $OldObj.Clone()
$NewObj.RecordData.IPv4address=[System.Net.IPAddress]::parse("10.184.12.73")
Set-DnsServerResourceRecord -NewInputObject $NewObj -OldInputObject $OldObj -ZoneName "asd.com" -PassThru
</powershell>
AWS CLI example:
aws ec2 run-instances --image-id ami-2fb56342 --instance-type m3.large --user-data file://user_data.txt --subnet-id subnet-fbc42a3 --security-group-ids sg-fbc42a3 --key-name jason-test
Running Commands on Your Linux Instance at Launch
Executing Scripts on Windows Instance at Launch
Configuring a Windows Instance Using EC2Launch
Configuring a Windows Instance Using the EC2Config Service
Managing Windows Instance Configuration
PowerShell - About Execution Policies