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 more than 70% of websites use PHP.
This repo provides CloudFormation templates to provision EC2 instances with option to specify PHP version, web server engine and database engine. The instances can be used for software development or deployment of PHP based web applications such as WordPress and Moodle.
The template provides the following features:
- Amazon Linux 2023, Ubuntu/Ubuntu Pro 22.04/24.04, or Amazon Linux 2
- Applications
- Apache or Nginx web server
- MySQL, MariaDB or PostgreSQL database server
- PHP
- Amazon Linux: PHP 8 with additional PECL extensions (imagick, apcu, memcached, redis, igbinary, msgpack, lzf, lz4, zstd, etc) compiled*
- Ubuntu Linux: PHP 5.6, 7.x or 8.x from Ondřej Surý's ppa:ondrej/php repository
- Composer
- Redis and Memcached in memory database
- Certbot for free HTTPS certificate
- Amazon Route 53 hosted zone access for use with certbot-dns-route53 DNS plugin
- Docker Engine (optional)
- MountPoint for Amazon S3 for mounting S3 bucket as local file system
- Amazon S3 bucket access for use with Mountpoint with S3
- AWS CLI v2 with auto-prompt
- Amazon CloudWatch agent
- AWS CodeDeploy agent
- Remote Administration
- Amazon DCV remote display protocol server for GUI access (optional: Amazon Linux 2/Ubuntu Linux)
- SSM Session Manager for secure shell access
- EC2 Instance Connect for SSH access
- Webmin web-based system administration (optional)
- AWS Services
- AWS Backup to protect EC2 instance data (optional)
- Amazon CloudFront CDN with support for VPC Origin (optional)
Although this repository is released under the MIT-0 license, its CloudFormation template uses features from MySQL Community Edition and Webmin which are licensed under GPL and BSD-3-Clause license respectively.
Usage indicates acceptance of DCV EULA and 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)
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
/osVersion
: Intel/AMD x86_64 or Graviton arm64. Default isGraviton (arm64)
.instanceType
: EC2 instance types. Do ensure type matches processor architecture. Default ist4g.xlarge
burstable instance type. For best performance, consider newer M7g and M8g Graviton instanceec2TerminationProtection
: enable EC2 termination protection to prevent accidental deletion. Default isYes
Network
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 source prefix to remote administration services, e.g.1.2.3.4/32
. You can get your source IP from https://checkip.amazonaws.com. Default is0.0.0.0/0
. -
ingressIPv6
: allowed IPv6 source prefix to remote administration services. Use::1/128
to block all incoming IPv6 access. Default is::/0
-
allowSSHport
: allow inbound SSH. Option does not affect EC2 Instance Connect access. Default isYes
-
installDCV
: install graphical desktop environment and DCV server. Default isYes
-
installWebmin
: install Webmin web-based system administration tool. Default isNo
SSH, DCV and Webmin inbound access are restricted to
ingressIPv4
andingressIPv6
IP prefixes.
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 will attempt to use 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 access using 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 for use with Certbot certbot-dns-route53 DNS plugin. A*
value will grant access to all Route 53 zones in your AWS account. Permission is restricted to _acme-challenge.* TXT DNS records using resource record set permissions. Default is empty string for no accessinstallDocker
(optional): install Docker Engine (also known as Docker CE) from Docker repository or Linux OS package repository. Default isNo
Amazon CloudFront
enableCloudFront
: create a Amazon CloudFront distribution to your EC2 instance. Associated charges are listed on Amazon CloudFront # page. Default isNo
originType
: eitherEC2
custom origin orVPC origin
. VPC Origin allows CloudFront to deliver content even if your EC2 instance is in a VPC private subnet. Refer to documentation for supported AWS Regions. Default isEC2
EBS
volumeSize
: Amazon EBS volume sizevolumeType
: EBS General Purpose Volume type
Backup
enableBackup
: EC2 data protection with AWS Backup. Associated charges are listed on AWS Backup # page. Default isYes
scheduleExpression
: start time of backup using CRON expression. Default is 1 amscheduleExpressionTimezone
: timezone in which the schedule expression is set. Default isEtc/UTC
deleteAfterDays
: number of days after backup creation that a recovery point is deleted. Default is35
The following are available on Outputs section
EC2console
: EC2 console URL to manage your EC2 instanceEC2instanceConnect
(if available, Linux): EC2 Instance Connect URL. Functionality is only available under certain conditionsEC2serialConsole
: EC2 Serial Console URL. Functionality is available under certain conditions.SSMsessionManager
orSSMsessionManagerDCV
: SSM Session Manager URLWebUrl
: EC2 web server URLDCVwebConsole
(where applicable): DCV web browser client URL#. Login as the user specified in Description fieldWebminUrl
(where applicable): Webmin URL link. Set the root password by runningsudo passwd root
usingEC2instanceConnect
,SSMsessionManager
or SSH session firstCloudFrontConsole
(where applicable): CloudFront console URL linkCloudFrontURL
(where applicable): CloudFront distribution URL, e.g.https://d111111abcdef8.cloudfront.net
#Native DCV clients can be downloaded from https://www.amazondcv.com/.
To troubleshoot any installation issue, you can view contents of the following log files (if available)
/var/log/cloud-init-output.log
/var/log/install-cfn-helper.log
/var/log/install-sw.log
/var/log/install-php.log
/var/log/install-lamp.log
/var/log/install-dcv.log
Based on public articles about PHP performance (many thanks to the authors), the following enhancements were made:
- Default processor architecture is Graviton as per Improving performance of PHP for Arm64 and impact on AWS Graviton2 based EC2 instances and 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/
phpVersion
/fpm/php.ini
(Ubuntu) file to uncomment the line beginning withopcache.file_cache=/var/www/.opcache
and restart php-fpm.
Amazon CloudFront (enableCloudFront
) supports HTTPS. You can use AWS Certificate Manager to request a public certificate for your own domain and associate it with your CloudFront distribution.
The EC2 instance uses a self-signed certificate for HTTPS. You can use Certbot to obtain and install Let's Encrypt certificate on your web server.
Ensure you have a domain name whose DNS entry resolves to your EC2 instance IP address. If you do not have a domain, you can register a new domain using Amazon Route 53 and create a DNS A record.
- From terminal, run the below command and follow instructions.
sudo certbot --apache
-
From terminal, run the below command and follow instructions.
sudo certbot --nginx
Apache and Nginx plugin uses HTTP-01 challenge, and require HTTP port 80 to be accessible from public internet
The certbot-dns-route53 option requires your DNS to be hosted by Route 53. It supports wildcard certificates and domain names that resolve to private IP addresses. Ensure that Route 53 zone access is granted by specifying r53ZoneID
value. 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
Refer to Certbot site for help with this tool.
Amazon CloudWatch agent is installed, and enables collection of EC2 system-level metrics and AWS X-Ray traces.
The template configures agent to collect memory utilization metrics. You can configure Cloudwatch agent to collect other data as follows.
Create agent configuration file. You can use agent configuration file wizard:
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
After config.json
file is created, start CloudWatch agent:
sudo systemctl enable amazon-cloudwatch-agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
Refer to How do I install and configure the unified CloudWatch agent to push metrics and logs from my EC2 instance to CloudWatch? for more details.
If you are looking to compile PHP extensions on AL2023, refer to community article How do I compile PHP extensions on Amazon Linux 2023?
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
If you enable AWS Backup, you can restore your EC2 instance from recovery points (backups) in your backup vault. The CloudFormation template creates an IAM role that grants AWS Backup permission to restore your backups. Role name can be located in your CoudFormation stack Resources section as the Physical ID value whose Logical ID value is backupRestoreRole
To futher secure your EC2 instance, you may want to
- Disable DCV web browser client by removing
nice-dcv-web-viewer
package- Use DCV (
installDCV
) native clients for remote access
- Use DCV (
- Restrict remote administration access to your IP address only (
ingressIPv4
andingressIPv6
) - Disable SSH access from public internet (
allowSSHport
)- Use EC2 Instance Connect or SSM Session Manager for in-browser terminal access
- Start a session using AWS CLI or SSH with Session Manager plugin for the AWS CLI
- Use AWS Backup (
enableBackup
) for EC2 data protection- Enable AWS Backup Vault Lock to prevent backups from accidental or malicious deletion and for protection from ransomware
- Deploy EC2 instance in a private subnet
- Use Application Load Balancer or Amazon CloudFront (
enableCloudFront
) with VPC Origin for public internet access - Use AWS Certificate Manager to request a public HTTPS certificate and associate it with your Application Load Balancer or CloudFront distribution
- Use AWS WAF to protect your CloudFront distribution or Application Load Balancer
- Use Application Load Balancer or Amazon CloudFront (
- With Amazon CloudFront, additional inbound HTTP and HTTPS security groups with AWS-managed prefix list for Amazon CloudFront as source are created. You can remove public internet inbound (
0.0.0.0/0
) HTTP/HTTPS from your security group - Enable Amazon Inspector to scan EC2 instance for software vulnerabilities and unintended network exposure.
- Enable Amazon GuardDuty security monitoring service with Malware Protection for EC2
To remove created resources, you will need to
- Delete any recovery points in created backup vault
- Disable EC2 instance termination protection (if enabled)
- Delete CloudFormation stack
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.