AWS CloudFormation template to provision Amazon EC2 instance with PHP, Apache/Nginx, MySQL/MariaDB/PostgreSQL, i.e. LAMP, LEMP, LAPP or LEPP stack.
LAMP is an acronym for the operating system, Linux; the web server, Apache; the database server, MySQL (or MariaDB); and the programming language, PHP. It is a common open source web platform for many of the web's popular applications. Variations include LEMP which replaces web server with Nginx, LAPP which replaces database server with PostgreSQL, and LEPP which uses Nginx and PostgreSQL. According to W3Techs, PHP is used by more than 70%, and either Nginx or Apache is used by more than 60% of websites as of 2023.
This repo provides CloudFormation template to provision a EC2 instance with option to specify PHP version, web server engine (Apache or Nginx) and database engine (MySQL, MariaDB or PostgreSQL) to install. The EC2 instance can be used for software development or deployment of PHP based web applications such as WordPress and Moodle.
The template provides the following features:
- Choice of Amazon Linux 2023, Amazon Linux 2, Ubuntu 22.04 and Ubuntu Pro 22.04
- NICE DCV remote desktop streaming (Amazon Linux 2 and Ubuntu Linux)
- Apache or Nginx web server
- MySQL, MariaDB or PostgreSQL database server
- PHP 8.1 or PHP 8.2(Amazon Linux 2 and 2023) with common PHP extensions (imagick, apcu, memcached, redis, igbinary, msgpack, lzf, lz4, zstd, libsodium, xdebug, zip, etc for Amazon Linux)
- Composer
- Redis and Memcached in memory database
- EC2 Instance Connect for SSH access
- SSM Session Manager for secure shell access
- AWS CodeDeploy agent
- Amazon CloudWatch agent
- NFS client
- AWS CLI v2 with auto-prompt
- MountPoint for Amazon S3 for mounting S3 bucket as local file system
- (Optional) Amazon S3 bucket for use with Mountpoint with S3
- Certbot with apache, nginx and certbot-dns-route53 plugins
- (Optional) Amazon Route 53 hosted zone access for use with certbot-dns-route53 plugin
- EC2 IAM role for NICE DCV license verification, AWS Systems Manager, CloudWatch, Mountpoint for S3, Code Deploy, X-Ray and Route 53
Note that use of cloudformation template indicates acceptance of license agreements of all software that is installed in the EC2 instance.
Download .yaml file for the desired operating system (Amazon Linux 2, Amazon Linux 2023 or Ubuntu/Ubuntu Pro 22.04 server)
Login to AWS CloudFormation console. Choose Create Stack, Upload a template file, Choose File, select your .YAML file and choose Next. Enter a Stack name and specify parameters values.
EC2
ec2Name
: EC2 instance nameec2KeyPair
: EC2 key pair name. Create key pair if necessaryprocessorArchitecture
: Intel/AMD x86_64 or Graviton arm64. Default isGraviton (arm64)
.instanceType
: EC2 instance types. Do ensure type matches processor architecture. Default ist4g.large
burstable instance type. For best performance, consider M6g or M7g for general purpose workloads
Networking
vpcID
: VPC with internet connectivity. Select default VPC if unsuresubnetID
: subnet with internet connectivity. Select subnet in default VPC if unsuredisplayPublicIP
: set this toNo
if your EC2 instance will not receive public IP address. EC2 private IP will be displayed in CloudFormation Outputs section instead. Default isYes
assignStaticIP
: associates a static public IPv4 address using Elastic IP address. Default isYes
Remote Administration
ingressIPv4
: allowed IPv4 internet source prefix to SSH and NICE DCV ports, e.g.1.2.3.4/32
. You can get your source IP from https://checkip.amazonaws.com. Use127.0.0.1/32
to block incoming access from public internet. Default is0.0.0.0/0
.ingressIPv6
: allowed IPv6 internet source prefix to SSH and NICE DCV ports. Use::1/128
to block all incoming IPv6 access. Default is::/0
LAMP
webOption
:Apache
,Nginx
web server ornone
.phpVersion
: PHP version to install ornone
databaseOption
:MySQL
,MariaDB
,PostgreSQL
database server ornone
. MySQL option for Amazon Linux 2 and Amazon Linux 2023 uses MySQL Community Edition repository, where MySQL root password can be retrieved using the commandsudo grep password /var/log/mysqld.log
. Selectnone
if using external database such as Amazon RDS.s3BucketName
(optional): name of Amazon S3 bucket to grant EC2 instance to via IAM policy. Leave text field empty not to grant access. A*
value will grant the EC2 instance access to all S3 buckets in your AWS account and is usually not recommended. Default is empty.r53ZoneID
(optional): Amazon Route 53 hosted zone ID to grant access to. Enable this if your DNS is on Route 53 and you want to use Certbot with certbot-dns-route53 plugin to get HTTPS certificate. A*
value will grant access to all Route 53 zones in your AWS account. Permission is restricted to TXT DNS records only using resource record set permissions. Default is empty.
EBS
volumeSize
: Amazon EBS volume sizevolumeType
: EBS General Purpose Volume type
The following are available on Outputs section
EC2console
: EC2 console URL link to start/stop your EC2 instance or to get the latest IPv4 (or IPv6 if enabled) address.EC2instanceConnect
: EC2 Instance Connect URL link. Functionality is only available under certain conditions.SSMsessionManager
: SSM Session Manager URL link. Use this to change login user password. Password change command is in Description field.WebUrl
: EC2 web server URL linkDCVwebConsole
: NICE DCV web browser client URL link#. Login as the user specified in Description field
#Native NICE DCV clients can be downloaded from https://download.nice-dcv.com/.
Web browser client can be disabled by removing nice-dcv-web-viewer
package.
Based on public articles about PHP performance (many thanks to the authors), the following enhancements were made:
- Default processor architecture option is Graviton as per arm64 vs x86_64 for php
- PHP OPcache and JIT enabled: from Make your PHP 8 apps twice as fast (OPCache & JIT)
- FastCGI Process Manager (FPM): from PHP-FPM Cuts Web App Loading Times by 300%
- Apache MPM Event: from Apache Performance Tuning: MPM Modules
- Redis session store: from Highly Performant PHP Sessions with Redis
- Serialisation (igbinary,msgpack) and compression (lzf,zstd,lz4) extensions to reduce Redis/Memcached network traffic: from Strategies for Reducing Big Redis Traffic in Laravel
- PHP OPcache file cache configured as per PHP Opcache file cache but not enabled. To enable, edit
/etc/php.d/10-opcache.ini
(Amazon Linux) or/etc/php/8.1/fpm/php.ini
(Ubuntu) file to uncomment the line beginning withopcache.file_cache=/var/www/.opcache
and restart php-fpm.
Refer to Certbot site for help with this tool.
To being, create a DNS record entry that resolves to your EC2 instance IP address, and ensure assignStaticIP
is configured to Yes
in your CloudFormation stack.
Ensure that you have granted Route 53 hosted zone access by specifying r53ZoneID
value in your CloudFormation stack. From terminal, run the below command based on installed web server type and follow instructions.
- Apache
sudo certbot --dns-route53 --installer apache
- Nginx
sudo certbot --dns-route53 --installer nginx
- From terminal, run the below command and follow instructions.
sudo certbot --apache
- From terminal, run the below command and follow instructions.
sudo certbot --nginx
To improve performance, reliability, scalability, high availability and functionality, EC2 instance can be extended to use other services such as Amazon RDS, Amazon S3, Amazon ElastiCache and Amazon EFS, and with AWS SDK for PHP. Some useful resources that can help with the integration include:
- AWS Well-Architected
- AWS Architecture Center including Scaling PHP Applications on AWS
- PHP on AWS
- Moodle Reference Architecture
- Best Practices for WordPress on AWS
To futher secure your EC2 instance, you may want to
- Remove NICE DCV web browser client
- Restrict NICE DCV and SSH to your IP address only (
ingressIPv4
andingressIPv6
) - Disable SSH access from public internet. Use EC2 Instance Connect or SSM Session Manager for in-browser terminal access. If you have AWS CLI and Session Manager plugin for the AWS CLI installed, you can start a session using AWS CLI or SSH
- Use Amazon CloudFront with AWS WAF to protect your instance from DDoS attacks and common web threats. The AWS blog Accelerate and protect your websites using Amazon CloudFront and AWS WAF and CloudFront dynamic websites CloudFormation template may help with CloudFront distribution setup. When using CloudFront, you can restrict your EC2 instance HTTP and HTTPS port access to CloudFront IPs only. The CloudFormation template creates additional inbound HTTP and HTTPS security group rules with AWS-managed prefix list for Amazon CloudFront as source where possible.
- Backup data on your EBS volumes with EBS snapshots. You can setup automatic snapshots using Amazon Data Lifecycle Manager or AWS Backup (with AWS Backup Vault Lock for enhanced security posture)
- Enable Amazon GuardDuty security monitoring service with Malware Protection to detect the potential presence of malware in EBS volumes
AWS IP prefixes used by EC2 instance connect are documented in ip-ranges.json where .service is EC2_INSTANCE_CONNECT
. You can retrieve IP prefix for your AWS Region (e.g. ap-southeast-1) using the following command
curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | \
jq -r '.prefixes[] | select (.service=="EC2_INSTANCE_CONNECT" and .region=="ap-southeast-1")'
Output as follows
{
"ip_prefix": "3.0.5.32/29",
"region": "ap-southeast-1",
"service": "EC2_INSTANCE_CONNECT",
"network_border_group": "ap-southeast-1"
}
IP prefixes can also be retrieved using AWS Tools for PowerShell with the following command
Get-AWSPublicIpAddressRange -ServiceKey EC2_INSTANCE_CONNECT | Select Region, IpPrefix
Below is the current list as of January 2024.
Region | IpPrefix |
---|---|
cn-north-1 | 43.196.20.40/29 |
cn-northwest-1 | 43.192.155.8/29 |
us-gov-east-1 | 18.252.4.0/30 |
us-gov-west-1 | 15.200.28.80/30 |
af-south-1 | 13.244.121.196/30 |
ap-east-1 | 43.198.192.104/29 |
ap-northeast-1 | 3.112.23.0/29 |
ap-northeast-2 | 13.209.1.56/29 |
ap-northeast-3 | 15.168.105.160/29 |
ap-south-1 | 13.233.177.0/29 |
ap-south-2 | 18.60.252.248/29 |
ap-southeast-1 | 3.0.5.32/29 |
ap-southeast-2 | 13.239.158.0/29 |
ap-southeast-3 | 43.218.193.64/29 |
ap-southeast-4 | 16.50.248.80/29 |
ca-central-1 | 35.183.92.176/29 |
eu-central-1 | 3.120.181.40/29 |
eu-central-2 | 16.63.77.8/29 |
eu-north-1 | 13.48.4.200/30 |
eu-south-1 | 15.161.135.164/30 |
eu-south-2 | 18.101.90.48/29 |
eu-west-1 | 18.202.216.48/29 |
eu-west-2 | 3.8.37.24/29 |
eu-west-3 | 35.180.112.80/29 |
il-central-1 | 51.16.183.224/29 |
me-central-1 | 3.29.147.40/29 |
me-south-1 | 16.24.46.56/29 |
sa-east-1 | 18.228.70.32/29 |
us-east-1 | 18.206.107.24/29 |
us-east-2 | 3.16.146.0/29 |
us-west-1 | 13.52.6.112/29 |
us-west-2 | 18.237.140.160/29 |
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.