Linux Apache MariaDB in the cloud


Contents

About LAM AWS

My main LAM AWS instance is a Dual stack (IPv4 and IPv6) web server, ssh proxy and ssh tunnel server. This main instance is currently required for a number of IPv6 workarounds I use to initialize an instance without a public IPv4 address. It is also used as an ssh proxy by my laptop, which currently does not have a public IPv6 address, for access to servers with only IPv6 connectivity. Since August of 2024 the main LAM AWS server instance provides access to my main git remote repo store.

This Linux Apache MariaDB (LAM) instance is in the cloud on Amazon Web Services (AWS) servers. I currently run my main instance in the Oregon (US West 2 region) which is one of the cheapest regions for AWS pricing. The inclusion of support for the Perl, Python and PHP application programming languages makes this a LAMP model web service software stack instance.

The LAM AWS server instance was created to host my public named host websites and be a backup of the mediawiki installation and home grown perl database web interface on the secure side of my main server. These utilize a MariaDB server on the same machine. The server is also used as an ssh proxy for browsing the web.

The main server instance is now running on a t4g.nano instance under an all upfront cost 36 month reservation. This prorates to less than $1.50 / month which is a considerable savings over the On Demand rate. The t4g.nano instance 36 month reservation covers 1 EC2 instance but does not include any EC2 EBS storage which is required for the Ubuntu Server image used for the Operating System. I pay $0.80 for 8 GB-Mo of General Purpose SSD (gp2) which is the standard configuration for the Latest Ubuntu Server image. I pay $0.30 for 1 GB-Mo of storage on the us-west-2 Oregon AWS Elastic File System (EFS) at the USD $0.30 per GB-Mo for Standard storage (USW2) rate. The AWS EFS storage is among the most expensive but it is extremely convenient to have a persistent parallel file system that can be mounted with the Linux nfs4 package available during the Instance Initialization. I pay $5.00 / month for an additional 50 GB-Mo of General Purpose SSD (gp2) for the volume to mirror the /Zz directory. I have an AWS EFS in all 30 regions I can currently access but the storage is negligible (less than 150K) on every EFS except my main one in the us-west-2 Oregon region.

My main private git remote store

Since August of 2024 the aws.lam1.us instance is my main private git remote store. This was also when I made GitLab my main public git remote store. Both the aws.lam1.us instance and GitLab have dual stack IP access supporting both IPv4 and IPv6 protocols. With the proper ssh_config and credentials matching an authorized_keys entry for the git@aws user the following will work:

git clone git@aws:<repo>

aws.lam1.us sites.lam1.us

The LAM AWS server instance was initially designed to utilize a t2.micro EC2 instance which is part of the AWS Free Tier offering starting in 2017. That offering includes 750 Hours / month of a t2.micro Elastic Compute Cloud (EC2) instance which is enough to run one instance 24/7. The instance can scale up by using a larger and more capable server and other options or scale down to a t4g.nano or other server sizes cheaper than a t2.micro except under the (AWS) Free Tier offering. Multiple groups of virtual hosts can all run on one server or a separate server can be used for each group or single host. Once the Free Tier was over the t2.micro server was found to cost less than $12.00 / month with the initial sizing and usage On Demand and less than $2.00 / month using a t3.nano EC2 instance reserved prepaid for 3 years. The less expensive t3.nano and then t4g.nano instances were tested and found to support the web and proxy services by being my cloud host after t2.micro hours got more expensive than free. The server is mostly idle although memory usage runs at 75% on a t3.nano and nearly 50% on a t2.micro.

A single LAM AWS server instance can host multiple websites, including a secure website, with Apache2 on Linux and includes MariaDB, Perl, Python, PHP and other common development tools. Additional packages installed support running MediaWiki and more. The LAM AWS server is built on the latest Ubuntu Server Amazon Machine Image (AMI) with an EBS General Purpose (SSD) Volume. The resulting image is similar enough to the Linux Mint distribution I use on the newer machines at home and on my laptop so that cloning my MediaWiki and lam databases from the main server to either an aws instance or Linux Mint machine can be done with the same procedure.

In 2023 the LAM AWS VPC in the us-west-2 Oregon region was modified with an Amazon provided IPv6 CIDR block and the subnet for each availability zone allocated a subset of the block and configured to automatically assign an IPv6 address to a new instance interface. In 2024 the LAM AWS VPC was modified in an additional 29 AWS regions and an EFS created and populated and the cloud-init process enhanced so that instances can be launched with or without a public IPv4 address on either x86 or ARM processor types with any of the latest Debian, Ubuntu or Amazon Linus operating system AMIs. As of 2024 the us-west-2 Oregon region is where my main instance runs and is the only AWS instance that has the additional 50 GB-Mo of General Purpose SSD (gp2) volume to mirror the /Zz directory. The us-west-2 Oregon efs is the only one populated with the git repositories of the remote and all the initialization files. Until 2024 the us-west-2 Oregon region was the only one where I operated.

LAM AWS resources

Public IPv4 Address

Since 2023 the main aws.lam1.us instance supports dual stack access via IPv4 and IPv6. It is the main workaround allowing the initialization of a LAM AWS instance without a public IPv4 address.

AWS started charging for a Public IPv4 Address in February of 2024. This doubled the cost of running one of it's smallest EC2 instances.

PublicIPv4='--no-associate-public-ip-address' # No Public IPv4 address
PublicIPv4='--associate-public-ip-address' # Public IPv4 address costs $43.80/Year

In 2023, when I found out AWS would begin charging for each public IPv4 address, I enabled a default IPv6 address from the 2600:1f14:3d86:2c00::/56 CIDR block for EC2 instance launched in my us-west-2 AWS LAM VPC and modified the aws-web-anywhere-alt-ssh-port Security Group to allow for IPv6 traffic. Because the ISP I use in Alaska does not yet support IPv6 and I don't know that any are available I must continue to use a Public IPv4 address for my main LAM AWS VPC EC3 instance. I detailed all 30 of the Amazon provided /56 IPv6 CIDR blocks for my VPC in each region in the Modify AWS VPC for IPv6 page I created.

I found that the public IPv4 addresses AWS optionally provided for an EC2 instance are implemented as NAT (Network Address Translation) at the gateway.

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 all EC2 images with only a limited number of inbound ports open. The definition details are:

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 and NFS traffic only on the private interface (172.31.0.0/16) or the IPv6 CIDR block for the VPC. 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 over either IPv4 or IPv6.

The us-west-2 Oregon has an additional Inbound SSH rule for each of the 30 IPv6 CIDR blocks AWS assigned my VPC for the region. All 30 of these Inbound SSH rules should be in every region but I skipped adding 26 of the rules to the additional regions when originally configuring them in 2024.

A separate EFS security group with just the 172.31.0.0/16 NFS for EFS inbound rule is attached to the interfaces for each Availability Zone in the region when creating the EFS for that region.

Use the default VPC for the AWS Region

The default VPC for the AWS Region includes a default subnet in each Availability Zone providing up to 4,096 addresses per subnet, a few of which are reserved for AWS use. This gives the LAM AWS VPC it's own private address space (172.31.0.0/16) and each EC2 instance gets an IP address within this space. The default VPC in each AWS Region also includes an attached internet gateway, a route in the main route table that sends all traffic to the internet gateway, and DNS settings that automatically assign public DNS hostnames to instances with public IP addresses and enable DNS resolution through the Amazon-provided DNS server.

KEYPAIR=lam-arsc

Prior to my expansion into other regions I had let AWS create an aws-nwo-lam1 key pair and I used that to access instances launched in us-west-2 Oregon. Quickly I was adding the passphrase protected key pair I have been using on my laptops since working at ARSC to every cloud-init file. The AWS key pairs are managed in the EC2 area of the console and not the VPC area but they are only available in the region that they they are created or imported into. I decided to import my main key into all the regions which eliminates the need to use the key pair I had ley Amazon create for me in 2017.

EFS=value-not-used

The EFS name value pair as an AWS instance tag was never utilized during initialization and the (AWS) Elastic File System (EFS) directory with a file for each region specifying the EFS name was created on my GitHub pages website instead to allow me to mount the LAM aws-efs for the region the instance was launched in. I am avoiding using the aws Command Line Interface (CLI) which is not available on an AWS Ubuntu instance without a Public IPv4 address.

The LAMP security group ID is unique for each region

REGION=us-west-2 #  us-west-2 Oregon my main region passed test 02
SECURITY_GROUP=sg-3bda0647 # aws-web-anywhere-alt-ssh-port us-west-2 Oregon

Prior to February 2024 when AWS started charging for a public IPv4 address over and above the hourly charge for running the instance I had only started instances in the us-west-2 Oregon region. In February I created the Modify AWS VPC for IPv6 page and modified the AWS VPC defaults for a number of regions and activated all the regions that were not previously activated. One of the steps is to create a security group which is now a parameter of the aws ec2 run-instances command I use to launch an instance.

REGION=us-east-1 # us-east-1 N. Virginia passed test 02 passed test 03
SECURITY_GROUP=sg-03320ad0fec07ba77 # aws-web-anywhere us-east-1
REGION=ca-central-1 # ca-central-1 Canada passed test 02 passed test 03
SECURITY_GROUP=sg-0ef4fef22698bcd40 # aws-web-anywhere ca-central-1
REGION=us-east-2 # us-east-2 Ohio passed test 02 passed test 03
SECURITY_GROUP=sg-0e742c1aadfffa653 # aws-web-anywhere us-east-2
REGION=us-west-1 # us-west-1 N. California passed test 02 passed test 03
SECURITY_GROUP=sg-0b2cbef29ecc3ecd2 # aws-web-anywhere us-west-1
REGION=eu-central-1 # eu-central-1 Frankfurt passed test 01 passed test 03
SECURITY_GROUP=sg-043484886d8ef0bc2 # aws-web-anywhere eu-central-1
REGION=eu-west-1 # eu-west-1 Ireland passed test 02 passed test 03
SECURITY_GROUP=sg-0b96ad2c4a0c62d9f # aws-web-anywhere eu-west-1
REGION=eu-north-1 # Stockholm (sebnets a, b, c) passed test 01 passed test 04b No t3a.nano
SECURITY_GROUP=sg-0b924f3ad0746fb5e # aws-web-anywhere
REGION=eu-central-2 # eu-central-2 Zurich (sebnets a, b, c) passed test 01 passed test 04 No t3a.nano
SECURITY_GROUP=sg-0d7a0136e28817ffd # aws-web-anywhere
REGION=eu-south-1 # eu-south-1 Milan (Italy) (sebnets a, b, c) passed test 01 passed test 04d
SECURITY_GROUP=sg-0a076e83dc883ad15 # aws-web-anywhere eu-south-1 Milan (Italy)
REGION=af-south-1 # af-south-1 Cape Town (sebnets a, b, c) passed test 01 passed test 04 No t3a.nano
SECURITY_GROUP=sg-018c1aae18c0e566b # aws-web-anywhere
REGION=eu-west-2 # eu-west-2 London (subnets a, b, c) passed test 01 passed test 04b
SECURITY_GROUP=sg-094710e95749e4318 # aws-web-anywhere
REGION=eu-west-3 # eu-west-3 Paris (subnets a, b, c) passed test 01 passed test 04b
SECURITY_GROUP=sg-06b1313e990e886e7 # aws-web-anywhere
REGION=sa-east-1 # sa-east-1 Sao Paulo (South America) (subnets a, b, c) passed test 01 passed test 03
SECURITY_GROUP=sg-0be16e2ef0697e8a7 # aws-web-anywhere
REGION=ap-northeast-1 # ap-northeast-1 Tokyo (subnets a, c, d) passed test 01 passed test 04e
SECURITY_GROUP=sg-08a18afbbbf99c26e # aws-web-anywhere
REGION=ap-southeast-1 # ap-southeast-1 Singapore (subnets a, c, d) passed test 01 passed test 04b
SECURITY_GROUP=sg-01752ca41332e7564 # aws-web-anywhere
REGION=ap-southeast-2 # ap-southeast-2 Sydney (subnets a, b, c) passed test 01 passed test 04
SECURITY_GROUP=sg-0e1819221520221dd # aws-web-anywhere
REGION=ap-northeast-2 # ap-northeast-2 Seoul (subnets a, b, c, d) most are only 3 passed test 01 passed test 04f
SECURITY_GROUP=sg-0b773851f304ba99a # aws-web-anywhere
REGION=ap-northeast-3 # ap-northeast-3 Osaka (subnets a, b, c) passed test 01 passed test 04c No t3a.nano
SECURITY_GROUP=sg-0e35405e1e8ef33bb # aws-web-anywhere
REGION=ap-south-1 # ap-south-1 Mumbai (subnets a, b, c) passed test 01 passed test 04
SECURITY_GROUP=sg-02c9967bd1c51cd28 # aws-web-anywhere
REGION=ca-west-1 # ca-west-1 Calgary (subnets a, b, c) passed test 01 passed test 04c No t3a.nano
SECURITY_GROUP=sg-0c6c9b55fc89bd275 # aws-web-anywhere
REGION=ap-southeast-4 # ap-southeast-4 Melbourne (subnets a, b, c) passed test 01 passed test 01 No t3a.nano
SECURITY_GROUP=sg-09f94b9a07c0f44c7 # aws-web-anywhere
REGION=me-south-1 # me-south-1 Bahrain (subnets a, b, c) passed test 01 passed test 04f No t3a.nano
SECURITY_GROUP=sg-026a4253f70941de7 # aws-web-anywhere
REGION=me-central-1 # me-central-1 United Arab Emirates (UAE) (subnets a, b, c) passed test 01 passed test 04 No t3a.nano
SECURITY_GROUP=sg-07791babc4c684823 # aws-web-anywhere
REGION=il-central-1 # il-central-1 Tel Aviv (Israel) (subnets a, b, c) passed test 01 passed test 04d No t3a.nano
SECURITY_GROUP=sg-03aa12578389c5a88 # aws-web-anywhere
REGION=ap-south-2 # ap-south-2 Hyderabad (India) (subnets a, b, c) passed test 01 passed test 03 No t3a.nano
SECURITY_GROUP=sg-0a5e33cec7b147f07 # aws-web-anywhere
REGION=ap-southeast-3 # ap-southeast-3 Jakarta {Indonesia) (subnets a, b, c) passed test 01 passed test 04f No t3a.nano
SECURITY_GROUP=sg-06ef74b2b06ac0f64 # aws-web-anywhere
REGION=eu-south-2 # eu-south-2 Spain (subnets a, b, c) passed test 01 passed test 04 No t3a.nano
SECURITY_GROUP=sg-074d970a9038a9cac # aws-web-anywhere
REGION=ap-east-1 # ap-east-1 Hong Kong (subnets a, b, c) passed test 01 No t3a.nano
SECURITY_GROUP=sg-0b668965bee1e8119 # aws-web-anywhere
REGION=ap-southeast-5 # ap-southeast-5 Asia Pacific (Malaysia)
SECURITY_GROUP=sg-08a513d15fdd89efb # aws-web-anywhere ap-southeast-5

In February of 2024 I requested a /56 IPv6 CIDR block for my LAM AWS VCP in all of the 28 regions currently available to me. I enabled 12 regions that were not enabled for my account to get to 28 regions available to me. I was pleased that by default AWS assigned over 4.2 Sextillion IPv6 addresses for each of the 28 regions where I asked for an IPv6 CIDR block from the AWS pool. So far I have only tested the aws-nwo-lam1-Ubuntu-CloudInit-ARM-No-Public-IPv4.txt cloud-init file in regions other than us-west-2 Oregon which has been my only region for the over six years I have been using AWS so far.

Use a persistent parallel file system

The (AWS) Elastic File System (EFS) directory with a file for each region specifying the EFS name was created on my GitHub pages website to allow me to mount the LAM aws-efs for the region the instance was launched in.

The EFS directory is used by the CloudInit directives during initialization of my AWS EC2 instances. The nfs-common additional package is required to mount the persistent Amazon Web Services Elastic File System. Once the nfs-common package is installed the nfs4 mount can be implemented. Since an additional package is required the mount is performed within the runcmd section and cannot be run earlier in the bootcmd section.

NFSv4 uses only one IP port, 2049, to run the service which simplifies controlling access.

In 2023 while investigating the internet via IPv4, IPv6 or a dual stack after learning AWS will start charging $43.80 per year for each public IPv4 address in use I found no way to have the EFS resource provisioned with IPv6 addresses. By default AWS creates a private IPv4 subnet for each availability zone within a region and automatically provisions resource names resolved by DNS to private IPv4 addresses within the subnets. This is all within the VPC (Virtual Private Cloud) created by default for you within a region where you deploy resources. I was able to modify my VPC for IPv6 but had to run dual stack EC2 instances to access the EFS. I learned that the public IPv4 addresses AWS can optionally provide for an EC2 instance are implemented as NAT (Network Address Translation) at the gateway.

Use a persistent 48G General Purpose SSD EBS volume

A second EBS volume was created to hold a copy of my /Zz by Date data in 2020. This copy is synced daily with the main copy on my AK LAN main server as long as ak20 is available via ssh. I started a t3.large EC2 instance with 8GiB memory to handle the initial population from the most recent Zz*tgz backup. The t3.nano I normally run could not handle the initial population task but has no problem with the daily rsync jobs. The volume is currently 87% utilized and I have already grown it from an original 44G size. The 48G of EBS costs an additional $4.80 a month and is available to only one EC2 instance.

A snapshot of this volume is created daily and retained for 15 days.

LAM AWS command line options

Launch a single ec2 instance specifying instance type and size
aws ec2 run-instances --count 1 --instance-type ${INSTANCE_TYPE}
Get a public IP address or not
${PublicIPv4}
Launch using my key
--key-name aws-nwo-lam1
Use a predefined security group
--security-group-ids sg-3bda0647
The initial Operating System / Architecture specific Amazon Machine Image to use
--image-id ${AMI}
Specify an instance Name tag
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=${KEYNAME}}]"
The Name Tag Value appears in the AWS EC2 Instances page along with Instance type, ID and state.
Specify the file with the user data
--user-data file://${CLOUD_INIT}

A number of the command line options are specified by variables mostly dependent on the Operating System / Architecture / PublicIPv4 options and the values are detailed in the following sections.

LAM AWS EC2 instance initialization by Operating System / Architecture / PublicIPv4

I initially created CloudInit directives only for Ubuntu Server and only the x86-64 architecture. This was originally on x86-64 Ubuntu Server 16.04 LTS, then x86-64 Ubuntu 18.04 LTS, then x86-64 Ubuntu Server 20.04 LTS and x86-64 Ubuntu Server 22.04 LTS.

The first variant was the CloudInit directives to have ssh on port 443 instead of https allowing me to setup a SSH SOCKS5 Proxy server on port 443 in some environments such as on hotel / resort Wi-Fi. This variant does not support the secure site where Mediawiki and other MariaDB web applications live.

In 2022 After upgrading to x86-64 Ubuntu Server 22.04 LTS I created an x86-64 Amazon Linux 2 initialization.

In 2023 I created an x86-64 Amazon Linux 2023 initialization after it became available in March. I followed in 2023 with ARM Amazon Linux 2023, and ARM Ubuntu Server 22.04 LTS initialization scripts. I then added Debian 12 scripts for both x86-64 and ARM architectures.

In 2023 I added the PublicIPv4 option.

Amazon Instance Type by Architecture and size

INSTANCE_TYPE=t4g.nano; # ARM 0.5 GiB 2 vCPU $0.0042 / hour = $0.1008 / day ~= $3.024 / month
INSTANCE_TYPE=t3a.nano; # x86 0.5 GiB 2 vCPU $0.0047 / hour = $0.1128 / day ~= $3.384 / month
INSTANCE_TYPE=t3.nano; # x86 0.5 GiB 2 vCPU $0.0052 / hour = $0.1248 / day ~= $3.74 / month
INSTANCE_TYPE=t2.nano; # x86 0.5 GiB 1 vCPU $0.0058 / hour = $0.1392 / day ~= $4.176 / month
INSTANCE_TYPE=t4g.micro; # ARM 1 GiB 2 vCPU $0.0084 / hour = $0.2016 / day ~= $6.048 / month
INSTANCE_TYPE=t3a.micro; # x86 1 GiB 2 vCPU $0.0094 / hour = $0.2256 / day ~= $6.768 / month
INSTANCE_TYPE=t3.micro; # x86 1 GiB 2 vCPU $0.0104 / hour = $0.2496 / day ~= $7.488 / month
INSTANCE_TYPE=t2.micro; # x86 1 GiB 1 vCPU $0.0116 / hour = $0.2784 / day ~= $8.352 / month
INSTANCE_TYPE=t4g.small; # ARM 2 GiB 2 vCPU $0.0168 / hour = $0.4032 / day ~= $12.096 / month
INSTANCE_TYPE=t3a.small; # x86 2 GiB 2 vCPU $0.0188 / hour = $0.4512 / day ~= $13.536 / month
INSTANCE_TYPE=t3.small; # x86 2 GiB 2 vCPU $0.0208 / hour = $0.4992 / day ~= $14.976 / month
INSTANCE_TYPE=t4g.medium; # ARM 4 GiB 2 vCPU $0.0336 / hour = $0.8064 / day ~= $24.192 / month
INSTANCE_TYPE=t3a.medium; # x86 4 GiB 2 vCPU $0.0376 / hour = $0.9024 / day ~= $27.072 / month
INSTANCE_TYPE=t3.medium; # x86 4 GiB 2 vCPU $0.0416 / hour = $0.9984 / day ~= $29.952 / month
INSTANCE_TYPE=t4g.large; # ARM 8 GiB 2 vCPU $0.0672 / hour = $1.6128 / day ~= $48.384 / month
INSTANCE_TYPE=t3a.large; # x86 8 GiB 2 vCPU $0.0752 / hour = $1.8048 / day ~= $54.144 / month
INSTANCE_TYPE=t3.large; # x86 8 GiB 2 vCPU $0.0832 / hour = $1.9968 / day ~= $59.904 / month

Each specific Initial AMI will only launch with a matching instance type Architecture.

Amazon Machine Image by Operating System / Architecture

Amazon Machine Image (AMI)s are available for a number of Operating System / Architecture configurations. A number of AMIs are supported and maintained by AWS, some provided by the AWS community and custom AMIs can be made. I could create a custom AMI but instead use a AWS provided AMI provided without additional charge and perform the initialization with the CloudInit directives. The initialization takes a few minutes but I avoid having to pay for the storage of the AMI as an EBS snapshot.

Each AMI is for a Region, Operating system, Architecture, and Storage for the root device. I use Oregon (US West 2) Region images with an Elastic Block Store (EBS) root device. I have CloudInit directives for Ubuntu server 22.04, Debian 12, Amazon Linux 2, and Amazon Linux 2023 for both x86 and ARM Architectures.

In February of 2024 I started launching instances in other regions of AWS besides the us-west-2 Oregon region where I have been operating since 2017. Before launching an instance in a new region I Modify AWS VPC for IPv6 since my initial testing is about running an instance with a Public IPv6 address but without a Public IPv4 that AWS is now charging a ludicrous amount for starting this month. I was testing arm64 Ubuntu 22.04 LTS which has an issue with package management on instances without a Public IPv4 address and decided to see if it affected other images since there is a separate image for each region.

For Ubuntu I use the Ubuntu image locator for ec2 and search for arm64 and the region to find the latest build for my testing. The rest of this section has cloud-init files for the us-west-2 Oregon region and are generally updated when new images appear in the Launch instances Quick Start section for selecting the AMI.

LAM AWS user-data is a set of CloudInit directives

The LAM AWS server is initialized with CloudInit directives to install the necessary packages, configuration and content on top of a generic Server image. All the directives in a file can be specified with the user-data parameter or in Advanced Options of the launch page from the AWS web console. The directives can also be pasted into the text box when using the web console. The CloudInit package is a great tool for AWS EC2 initialization.

Instance to take over lam1

If launched with the Public IPv4 address option a lam1 instance can be used as the main LAM AWS instance.

The main initialization directives update the Ubuntu server to support all the virtual hosts of the LAM AWS cloud and automatically assume the lam1 domain subset of hosts. Additional Dynamic Domain Name Service#Check-in from a Linux host operations can be performed to take over more or all of the lam1 domain subsets.

AMI=ami-06068bc7800ac1a83 # us-west-2	Jammy Jellyfish	22.04 LTS	amd64	hvm:ebs-ssd	20240530
AMI=ami-0b74dcc00bb584e51 # us-west-2	Jammy Jellyfish	22.04 LTS	arm64	hvm:ebs-ssd	20240530
PublicIPv4='--associate-public-ip-address' # Public IPv4 address costs $43.80/Year
CLOUD_INIT=/var/www/aws/aws-nwo-lam1-Ubuntu-CloudInit.txt
KEYNAME=lam1-Ubuntu-x86-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')
Instance designed to initiate without public IPv4 access
PublicIPv4='--no-associate-public-ip-address' # No Public IPv4 address
CLOUD_INIT=/var/www/aws/aws-nwo-lam1-Ubuntu-No-Public-IPv4-CloudInit.txt
KEYNAME=lam1-Ubuntu-No-Public-IPv4-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')

lam1 Instance running Ubuntu 24.04 Noble Numbat

lam1 Instance running Ubuntu 24.04 Noble Numbat rather than Ubuntu 22.04 Jammy Jellyfish

AMI=ami-0a87d8e805902d07d # us-west-2	Noble Numbat	24.04 LTS	amd64	hvm:ebs-ssd-gp3	20240615
AMI=ami-0ad27234b2a04a5ff # us-west-2	Noble Numbat	24.04 LTS	arm64	hvm:ebs-ssd-gp3	20240615
CLOUD_INIT=/var/www/aws/aws-nwo-lam1-Ubuntu-Noble-CloudInit.txt
KEYNAME=lam1-Ubuntu-Noble-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')
Instance designed to initiate without public IPv4 access
CLOUD_INIT=/var/www/aws/aws-nwo-lam1-Ubuntu-Noble-No-Public-IPv4-CloudInit.txt
KEYNAME=lam1-Ubuntu-Noble-No-Public-IPv4-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')

lam2 Instance 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. I run this instance only when I find my ssh access blocked when using someone else's WiFi such as from the laptop at a hotel or for testing.

PublicIPv4='--associate-public-ip-address' # Public IPv4 address costs $43.80/Year
CLOUD_INIT=/var/www/aws/aws-nwo-lam2-Ubuntu-CloudInit.txt # Ubuntu Server 22.04 Jammy Jellyfish
KEYNAME=lam2-Ubuntu-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')
This instance doesn't check in to a Dynamic Domain Name Service and requires a public IPv4

This instance uses github as the source of public repositories which means it does not support initializing without a public IPv4 address. It does not require the EFS or my aws.lam1.us instance to be running.

PublicIPv4='--associate-public-ip-address' # Public IPv4 address costs $43.80/Year
CLOUD_INIT=/var/www/aws/aws-lam2-Amazon-Linux-2-CloudInit.txt
KEYNAME=lam2-AL2-x86-port-443-${REGION}
AMI=ami-0de43e61758b7158c # Amazon Linux 2 Kernel 5.10 AMI 2.0.20231218.0 x86_64 HVM gp2

Like in What is missing, this instance doesn't check in to a Dynamic Domain Name Service.

lam2 Instance running Amazon Linux 2 rather than Ubuntu Server

This instance runs on Amazon Linux 2 rather than Ubuntu Server. There are a number of package differences and differences in Apache2 configuration. With the addition of EPEL and amazon-linux-extras repositories it supports being a LAM Alaska clone including the MediaWiki and other functions served by https.

AMI=ami-02e8e2a390064c712 # Amazon Linux 2 Kernel 5.10 AMI 2.0.20240529.0 x86_64 HVM gp2 us-west-2 Oregon
AMI=ami-0ad13aa6b186f8825 # Amazon Linux 2 LTS Arm64 Kernel 5.10 AMI 2.0.20240529.0 arm64 HVM gp2 us-west-2 Oregon
PublicIPv4='--associate-public-ip-address' # Public IPv4 address costs $43.80/Year
CLOUD_INIT=/var/www/aws/aws-nwo-lam2-Amazon-Linux-2-CloudInit.txt
KEYNAME=lam2-Amazon-Linux-2-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')
Instance designed to initiate without public IPv4 access
PublicIPv4='--no-associate-public-ip-address' # No Public IPv4 address
CLOUD_INIT=/var/www/aws/aws-nwo-lam2-Amazon-Linux-2-No-Public-IPv4-CloudInit.txt
KEYNAME=lam2-Amazon-Linux-2-No-Public-IPv4-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')

lam2 Instance running Amazon Linux 2023

AMI=ami-0b20a6f09484773af # Amazon Linux 2023 AMI 2023.4.20240611.0 x86_64 HVM kernel-6.1 us-west-2 Oregon
AMI=ami-00a0b62a1660255c0 # Amazon Linux 2023 AMI 2023.4.20240611.0 arm64 HVM kernel-6.1 us-west-2 Oregon
PublicIPv4='--associate-public-ip-address' # Public IPv4 address costs $43.80/Year
CLOUD_INIT=/var/www/aws/aws-nwo-lam2-Amazon-Linux-2023-CloudInit.txt
KEYNAME=lam2-AL2023-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')
Instance designed to initiate without public IPv4 access
PublicIPv4='--no-associate-public-ip-address' # No Public IPv4 address
CLOUD_INIT=/var/www/aws/aws-nwo-lam2-Amazon-Linux-2023-No-Public-IPv4-CloudInit.txt
KEYNAME=lam2-AL2023-No-Public-IPv4-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')

lam2 Instance running Debian 12

AMI=ami-0c2644caf041bb6de # Debian 12 (20231013-1532) x86_64 us-west-2 Oregon
AMI=ami-07564a05443c48891 # Debian 12 (20231013-1532) ARM us-west-2 Oregon
PublicIPv4='--associate-public-ip-address' # Public IPv4 address costs $43.80/Year
CLOUD_INIT=/var/www/aws/aws-nwo-lam2-Debian-CloudInit.txt
KEYNAME=lam2-Debian-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')
This instance is designed to initiate without public IPv4 access.
PublicIPv4='--no-associate-public-ip-address' # No Public IPv4 address
CLOUD_INIT=/var/www/aws/aws-nwo-lam2-Debian-No-Public-IPv4-CloudInit.txt
KEYNAME=lam2-Debian-No-Public-IPv4-${REGION}-$(echo ${INSTANCE_TYPE} | tr '.' '-')

Launch a LAM AWS EC2 instance from the command line

The awscli package includes the aws command which includes the ability to launch a new instance.

aws ec2 run-instances --count 1 --image-id ${AMI}  --region ${REGION} \
--instance-type ${INSTANCE_TYPE} --security-group-ids ${SECURITY_GROUP} \
--tag-specifications "ResourceType=instance,Tags=[\
{Key=Name,Value=${KEYNAME}},\
{Key=EFS,Value=fs-6f45fac6.efs.us-west-2.amazonaws.com}]" \
${PublicIPv4} --key-name ${KEYPAIR} --user-data \
file://${CLOUD_INIT}

Amazon Web Services (AWS)

The LAM AWS EC2 instance initializations perform the following:

This results in an instance using one of the http://lam1.duckdns.org or http://lam2.duckdns.org subdomains that is a LAM Alaska clone based on the latest daily backups.

LAM AWS Updates and Backups

Latest daily backup to persistent storage is used for initialization

The LAM AWS server instance hosting my public named host websites and a backup of the secure side of my main server is designed to use a set of CloudInit directives and a small amount of data on top of the latest Amazon Machine Image (AMI) on the default launch image page. The initialization takes a few minutes but this means I don't have to pay for the storage of a custom AMI.

Daily backups to the persistent parallel file system are used for a new instance initialization so that it is current except for changes made to the main server within the last 24 hours.

New instance initialization includes a full upgrade of the latest Amazon Machine Image

New instance initialization includes a full upgrade so testing after the launch of a new image should show if any updates that have not been applied to the current main running instance cause problems.

The latest Amazon Machine Image is specified as a command line option for the "aws ec2 run-instances" command. A new image on the default launch image page is tested when it appears and usually can be substituted without any other changes to the new instance initialization. Some package changes required changes to the new instance initialization when I did the major upgrade to Ubuntu 18.04 from Ubuntu 16.04 but most simply shorten the full upgrade performed during the new instance initialization.

CloudInit directives and a set of scripts control use and creation of daily backups

The CloudInit directives specified as user-data when launching a new instance are maintained in the files linked to above.

A set of scripts on the persistent parallel file system are included in daily backups on the main server to keep the backups up to date. Any configuration file changes from package defaults must be included in the backups and or applied during the new instance initialization.

Repos for LAM AWS Linux Apache MariaDB in the cloud

I have published some of the repos of the server configuration and the content in the html folder and an apache2 configuration for the websites to GitHub.

Log