A Cloud-init script that anyone could launch on AWS
I created a new aws-lam2-Ubuntu-CloudInit script that anyone could launch on Amazon Web Services (AWS).
ContentsA web, shell and proxy server built from a Generic Ubuntu Server image
The script builds a web, shell and proxy server from the Generic Ubuntu 20.04 Server image available at no additional charge over the cost of running the EC2 instance.
All the source is on GitHub and the creation and storage of a custom Amazon Machine Image is not required.
The web server is configured for three websites. The default website would be displayed if a domain name is pointed to the IP address or domain name of the running instance. A second website is configured if the browser gets to the site by IP address or the public-hostname assigned to the instance when it launched. The third website is configured for some domain names I have control of.
I can launch from the command line with:
aws ec2 run-instances --count 1 --image-id ami-0ecc74eca1d66d8a6 \ --instance-type t3.nano --security-group-ids sg-3bda0647 --tag-specifications \ 'ResourceType=instance,Tags=[{Key=Name,Value=aws-lam2-Ubuntu-20-04}]' \ --associate-public-ip-address --key-name aws-nwo-lam1 --user-data \ file:///var/www/aws/aws-lam2-Ubuntu-CloudInit.txt
LAM AWS command line options
- Launch a single ec2 instance of the t3.nano type which is cheapest or of the t2.micro type which is part of the AWS Free Tier offering.
- aws ec2 run-instances --count 1 --instance-type t3.nano
- Get a public IP address and launch using my key
- --associate-public-ip-address --key-name aws-nwo-lam1
- Use a predefined security group
- --security-group-ids sg-3bda0647
- Use the latest Ubuntu Server image
- --image-id ami-0ecc74eca1d66d8a6
- Specify the file with the user data
- --user-data file://<file name>
- ami-0ecc74eca1d66d8a6 This is the Ubuntu Server 22.04.1 LTS image for the US west 2 AWS region
- If you want to run this in another region, use the appropriate image which you can find at the bottom of the Launch instance wizard page.
- aws-nwo-lam1 This is my key from AWS Identity and Access Management for the IAM user I want to be able to access the instance.
- sg-3bda0647 This is a pre defined security group.
- t3.nano This is a very small instance and you would want to use the larger t2.mico to be eligible for the Free Tier.
Prerequisites
I would love to have someone test this script but can't think of who to ask. I have been retired for over five years so don't have co-workers I could ask. My friends and family are not really interested in what I do related to computers for fun.
AWS Account
I have a root user account that I almost never use and a separate AWS IAM user for that account that I use for everything. My user level access has access to a everything for the account including billing.
Unknown level of knowledge
I don't even remember all the steps in setting up the two sets of credentials and granting the proper level of access to the user account so I never have to use the root account but I remember there were lots of guidelines on the web.
This page is not a tutorial and is instead an example. It is also documentation for myself and has enough that I can launch the instance with copy and paste and even do the check in to a Dynamic Domain Name Service steps I documented below.
You can launch the instance from the AWS Console
You can launch the instance from the AWS Console from Services - EC2 - Instances - Launch Instance
As of December 2022 Ubuntu is one of OS choices along with Amazon, RedHat, Suse and many others. For each OS several versions may be available in a drop down list.
You can paste the data passed as a file on the command line into the User data box in the advanced section of the Configure Instance Details page.
You can even configure a new security group from the launch web interface although this is step six with many previous options to launch before seeing that page.
I am sure an advanced user could launch one of these instances from this post.
Install awscli and set credentials to use the command line
This awscli package is in the standard Ubuntu repositories. The .aws/credentials file has key information for aws-nwo-lam1 to launch an instance in my VPC and the .aws/config file holds us-west-2 as the region value where the instance is launched.
LAM AWS resources
Use a predefined security group
The security group definition controls the traffic within the Virtual Private Cloud and with the outside world. I use the same security group definition for multiple images with only a limited number of inbound ports open. The definition details are:
- GroupName - aws-web-anywhere-alt-ssh-port
- Inbound Port 22 TCP Rule - SSH from VPC - 172.31.0.0/20
- Inbound Port 80 Custom TCP Rule - HTTP - 0.0.0.0/0
- Inbound Port 443 Custom TCP Rule - HTTPS or SSH on an Alternate port - 0.0.0.0/0
- Inbound Port 55520 Custom TCP Rule - SSH on an Alternate port - 0.0.0.0/0
- Inbound Port 55593 Custom TCP Rule - IMAPS on an Alternate port - 0.0.0.0/0
- Outbound All/All 0.0.0.0/0
This security group definition allows web traffic on the standard ports from the public interface (0.0.0.0/0), Secure Shell on an alternate high numbered port and IMAPS on an alternate high numbered port. The security group definition allows Secure Shell on the standard port. The SSH SOCKS5 Proxy instance uses the same security group definition but is accepting Secure Shell traffic on the port that is normally used for Secure Web (HTTPS) traffic. The security group definition does allow outgoing traffic from the server over the public interface.
What is missing
The instance doesn't check in to a Dynamic Domain Name Service
My main lam2 script checks in as http://lam2.duckdns.org which is one of four names that along with the aws public-hostname can be used to access the customized website. The instance-type is also shown on the page as well as a link to the Cloud-init log. I can use this page to toggle between the four Dynamic Domain Names I use for the group of servers I use to support the websites.
From another instance in the same VPC I can use Secure Copy to get the private ubuntu resource archive to the new instance over the local area network with:
scp -p /mnt/efs/aws-lam1-ubuntu/ubuntu.t* <local-ipv4>:/home/ubuntu
On the new instance I can install these resources with:
tar -xzf ubuntu.tgz --directory /home/ubuntu
Check in and get a verbose response:
DDNS_NAME=lam2 echo url="https://www.duckdns.org/update?domains=${DDNS_NAME}&token=$(cat \ ~/.duckdns)&verbose=true&ip="| curl -k -K -; echo \ " for ${DDNS_NAME}.duckdns.org IP address update" ; echo
Upon successful completion the output with the verbose option will look like the following:
OK 69.178.104.164 UPDATED for lam2.duckdns.org IP address update
If the ubuntu resources were not installed the following error is reported:
cat: ~/.duckdns: No such file or directory
Alternately the Duck DNS token file can be created with:
echo {DuckDNStokenValue} > /home/ubuntu/.duckdns
The HTTPS port is an alternate SSH port
The main function of this AWS EC2 instance is to be a SSH SOCKS5 Proxy server on port 443.
Port 443 is normally used for HTTPS so is likely to be available even when other ports are blocked.
No MediaWiki, No HTTPS site defined or modules loaded
My main lam1 Cloud-init script has the HTTPS site definition in a private repository.
No mount of a persistent parallel file system
My main lam1 Cloud-init script utilizes an AWS Elastic File System (EFS) that all the instances can access as a persistent parallel file system. Private git repositories and other shared resources are on that filesystem.
Why the lam2 instance
The lam2 instance was a candidate to be modified so that anyone could launch it precisely because it did not have html/Private, MediaWiki or the databases that I only support on HTTPS.
I have had an AWS VPC since 2017 but early on added the private EFS and private S3 buckets as a source for initializing.
In 2020 I finally switched to git as my main VCS and decided to publish repos that did not need to remain private to GidHub because of it's value for documentation. Once I had published the aws Linux Apache MariaDB in the cloud, no-ssl Default unsecure site configuration and arsc Lawrence A. Murakami at ARSC repos to GitHub I realized I could launch the lam2 instance using only publicly available sources for the initialization.
The CloudInit file is a YAML data file
Technically the CloudInit file is not a script but a YAML data file. The data file contains a runcmd section with an array of commands that run sequentially and this is the bulk of my CloudInit files. The sequential sequence of commands section is in my mind the same as a script. The individual commands have to fit within the yaml rules which can introduce complexities such as when colons are needed in a command or it's arguments. The bootcmd section is also a sequential sequence of commands section that runs earlier in the initial boot and is run again on subsequent boots. The packages section is a list of packages to be installed during the initialization that happens after the bootcmd and before the runcmd sections. Some packages are installed by commands in the runcmd section to control timing.
This page was retrieved from my private MediaWiki instance
Most of the pages I end up publishing to the web are a Static Copy of a page in my private MediaWiki instance. In this case I use view source and copy the parts from to From: <!-- start content --> To: <!-- end content --> to a file and add Front Matter for Jekyll that will build the page to be published on GitHub Pages.
Log
- Sunday, December 11, 2022 Update for Ubuntu 22.04
- The glances application was problematic for initial versions of Ubuntu 22.04 and was removed from the packages section so that the instance could start.
- The glances application can be installed without problem after upgrade to Ubuntu 22.04.1
- The which, leafpad and commands compiled for Ubuntu 20.04 still work with Ubuntu 22.04
- August 4, 2020 Created this page using an Ubuntu 20.04 Amazon Machine Image (AMI)
Top of this document Sunday, December 11, 2022 @ 8:49:58 PM (Alaska Time)