In AWS CloudFormation, EC2 user data refers to the script or commands that can be passed to an EC2 instance during its launch or bootstrapping process. It allows you to automate the configuration and customization of your EC2 instances by executing scripts or running commands when the instance starts.
EC2 user data is typically used to perform tasks such as installing software, configuring applications, or setting up the environment on an EC2 instance. It provides a convenient way to automate these tasks without the need for manual intervention.
Hands-on with EC2 User Data
Here's an example of how you can use EC2 user data in AWS CloudFormation:
Resources:
MyKeyPair:
Type: "AWS::EC2::KeyPair"
Properties:
KeyName: "my-keypair"
PublicKeyMaterial: "AAAAB3NzaC1yc2EAAAADAQABAAAB...your-public-key... user@host"
MySecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: "Allow SSH access"
SecurityGroupIngress:
- CidrIp: "<your_ip_address>/32"
FromPort: 22
ToPort: 22
IpProtocol: "tcp"
MyEC2Instance:
Type: "AWS::EC2::Instance"
Properties:
ImageId: "ami-053b0d53c279acc90" # Ubuntu 22.04
InstanceType: "t2.micro"
KeyName: !Ref MyKeyPair
SecurityGroupIds:
- !Ref MySecurityGroup
UserData:
Fn::Base64: !Sub |
#!/bin/bash
apt-get update
apt-get install -y apache2
echo "Hello, World!" > /var/www/html/index.html
systemctl start apache2
In this CloudFormation template snippet, we define an EC2 instance (MyEC2Instance
) with a specific Amazon Machine Image (AMI) and instance type. The important part is the UserData
property.
The UserData
property is a base64-encoded string that contains the user data script. In this case, we're using the Fn::Base64
function to encode a multi-line Bash script. The script does the following:
Writes "Hello, World!" to a file named
index.html
in the/var/www/html
directory.Starts the
apache2
service, assuming the instance is running a Linux-based operating system with Apache HTTP Server installed.
When the EC2 instance is launched using this CloudFormation template, the user data script will be executed automatically during the instance's bootstrapping process. It ensures that the specified commands are run, enabling you to configure the instance as needed.
Note that user data scripts can vary depending on the operating system running on the EC2 instance and the requirements of your application or environment.
Fn::Base64 function
The Fn::Base64
function is an intrinsic function in AWS CloudFormation that allows you to encode a string as a base64 representation. It is commonly used in CloudFormation templates to encode sensitive data, such as user data scripts or configuration files, that need to be passed as parameters or properties.
The syntax for using Fn::Base64
function is as follows:
Fn::Base64: <string-to-encode>
You provide the string you want to encode as the argument to the Fn::Base64
function, and CloudFormation will encode it as a base64 string during the template execution.
For example, if you have a user data script in your CloudFormation template and you want to encode it using Fn::Base64
, you can use it as follows:
UserData:
Fn::Base64: |
#!/bin/bash
echo "Hello, World!" > /var/www/html/index.html
systemctl start apache2
In this example, the user data script is provided as a multi-line string. The Fn::Base64
function is used to encode the entire user data script, ensuring that it will be passed as a base64-encoded string to the EC2 instance during its launch.
The Fn::Base64
function is a convenient way to encode sensitive information or preserve the integrity of multiline strings in your CloudFormation templates. It is often used in conjunction with properties like UserData
, UserDataOverride
, or any other property where encoding as base64 is required.
Create SSH key pair and allow connection on port 22
For connecting to the MyEC2Instance
resource in your CloudFormation template, you need to specify the KeyName
property under the Properties
section of the AWS::EC2::Instance
resource.
At the same time, you need to allow SSH connection on port 22 from your IP address
To generate SSH keys on Linux machines, you can use the ssh-keygen
command, which is a built-in tool for managing SSH keys. Here's how you can generate SSH keys:
Open a terminal on your machine.
Run the following command to generate an SSH key pair:
ssh-keygen -t rsa -b 4096
This command generates an RSA key pair with a key length of 4096 bits. You can adjust the key type (-t
) and key length (-b
) according to your needs.
You'll be prompted to enter a file to save the key pair. By default, it will be saved in the
~/.ssh
directory with the filenamesid_rsa
(private key) andid_rsa.pub
(public key). If you want to use a different file name or location, you can specify it here.You'll also be prompted to enter a passphrase for the key pair. It's recommended to set a passphrase for added security. The passphrase is used to encrypt the private key, so you'll need to enter it each time you use the key.
Once you've entered the file name and passphrase (if any), the key pair will be generated. You'll see output similar to the following:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/your-username/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/your-username/.ssh/id_rsa.
Your public key has been saved in /home/your-username/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx your-username@your-hostname
The key's randomart image is:
+---[RSA 4096]----+
| .+. |
| . .o |
| . o.. |
| . .o. . |
| o . ..S . |
| . +..=.o o o |
| Eo+o=.+. = |
| =oo=.++ o |
| .+=oo.*.o |
+----[SHA256]-----+
The private key (id_rsa
) and the public key (id_rsa.pub
) files are now generated and saved in the specified location.
Change permissions:
chmod 400 id_rsa*
You can use the public key (id_rsa.pub
) to authenticate with remote servers by adding it to the appropriate ~/.ssh/authorized_keys
file on the remote machine. The private key (id_rsa
) should be kept secure and not shared with anyone.
That's it! You've successfully generated SSH keys.
Deploy CloudFormation Stack
To deploy your CloudFormation stack use the following command:
aws cloudformation create-stack --stack-name MyEC2Stack --template-body file://ec2-userdata.yaml
To delete your stack use the following command:
aws cloudformation delete-stack --stack-name MyEC2Stack
Verify EC2 User Data script execution
To check if the user data script was successfully executed on the EC2 instance launched with the template mentioned above, you can access the instance and inspect the execution logs or verify the changes made by the script. Here's how you can do it:
- Connect to the EC2 instance using SSH, as explained in a previous response. Run the following command:
ssh -i /path/to/your/private-key.pem ec2-user@<public-ip-address-or-dns-name>
Replace /path/to/your/private-key.pem
with the actual path to your private key file, and <public-ip-address-or-dns-name>
with the public IP address or DNS name of your EC2 instance.
- Once connected to the instance, you can check the execution logs of the user data script. The logs can be found in the
/var/log/cloud-init-output.log
file. You can use thecat
command to view the contents of the file:
cat /var/log/cloud-init-output.log
This file contains the output generated during the execution of the user data script. It will provide information about the commands executed and any errors or messages generated by the script.
- Additionally, you can verify the changes made by the user data script. In the example template provided, the script writes "Hello, World!" to the
/var/www/html/index.html
file and starts theapache2
service. You can check if these changes were applied successfully by examining the content of the file or accessing the web server running on the instance.
To view the content of the index.html
file, you can use the cat
command:
cat /var/www/html/index.html
If the user data script ran successfully, it should display "Hello, World!".
curl localhost
To check if the apache2
service is running, you can use the systemctl
command:
sudo systemctl status apache2
This command will show the status of the apache2
service. If it is active (running), then the service was started successfully by the user data script.
By inspecting the execution logs and verifying the changes made by the user data script, you can determine if it was successfully executed on the EC2 instance launched with the CloudFormation template.