Skip to content

CloudFormation (IaC) template to provision Apache or Nginx web server EC2 instance with PHP and MySQL/MariaDB/PostgreSQL.

License

Notifications You must be signed in to change notification settings

aws-samples/ec2-lamp-server

EC2-LAMP-Server

AWS CloudFormation template to provision Amazon EC2 web server with Apache/Nginx, PHP and MySQL/MariaDB/PostgreSQL.

Description

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.

Architecture Diagram

image

Overview of features

The template provides the following features:

Notice

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 of Amazon DCV indicates acceptance of DCV EULA.

By using the template, you accept license agreement of all software that is installed in the EC2 instance.

Requirements

Deploying using CloudFormation console

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 Instance

EC2 Network

  • vpcID: VPC with internet connectivity. Select default VPC if unsure
  • subnetID: subnet with internet connectivity. Select subnet in default VPC if unsure
  • displayPublicIP: set this to No if your EC2 instance will not receive public IP address. EC2 private IP will be displayed in CloudFormation Outputs section instead. Default is Yes
  • assignStaticIP: associates a static public IPv4 address using Elastic IP address. Default is Yes

Application Load Balancer (ALB)

  • enableALB: deploy Application Load Balancer with EC2 instance as target. Associated charges are listed on Elastic Load Balancing # page. Default is No
  • albScheme: either internet-facing or internal. An internet-facing load balancer routes requests from clients to targets over the internet. An internal load balancer routes requests to targets using private IP addresses. Default is internet-facing
  • albIpAddressType: IP address type, either IPv4, IPv4-and-IPv6 or IPv6. Default is IPv4
  • albSubnets: subnets for ALB. Select at least 2 AZ subnets in EC2 VPC

Select a subnet even if enableALB is No

ALB HTTPS listener

The above options only apply if enableALB is Yes

Amazon CloudFront

  • enableCloudFront: create a Amazon CloudFront distribution to your EC2 instance or ALB. Associated charges are listed on Amazon CloudFront # page. Default is No
  • originType: either Custom Origin or VPC Origin. Most AWS Regions support VPC Origins, which allow CloudFront to deliver content even if your EC2 instance is in a VPC private subnet. Default is Custom Origin

EC2 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 is 0.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 is Yes
  • installDCV: install graphical desktop environment and DCV server. Default is Yes
  • installWebmin: install Webmin web-based system administration tool. Default is No

SSH, DCV and Webmin inbound access are restricted to ingressIPv4 and ingressIPv6 IP prefixes.

LAMP

  • webOption: Apache or Nginx web server.
  • phpVersion: PHP version to install or none.
  • databaseOption: MySQL, MariaDB, PostgreSQL database server or none. MySQL option for Amazon Linux will attempt to use MySQL Community Edition repository, where MySQL root password can be retrieved using the command sudo grep password /var/log/mysqld.log. Select none 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 access
  • installDocker (optional): install Docker Engine (also known as Docker CE) from Docker repository or Linux OS package repository. Default is No

Amazon CloudFront

  • enableCloudFront: create a Amazon CloudFront distribution to your EC2 instance. Associated charges are listed on Amazon CloudFront # page. Default is No
  • originType: either Custom Origin or VPC origin. VPC Origin allows CloudFront to deliver content even if your EC2 instance or ALB is in a VPC private subnet. Refer to documentation for supported AWS Regions. Default is Custom Origin

EBS

Backup

  • enableBackup : EC2 data protection with AWS Backup. Associated charges are listed on AWS Backup # page. Default is Yes
  • scheduleExpression: start time of backup using CRON expression. Default is 1 am
  • scheduleExpressionTimezone: timezone in which the schedule expression is set. Default is Etc/UTC
  • deleteAfterDays: number of days after backup creation that a recovery point is deleted. Default is 35

CloudFormation Outputs

The following are available on Outputs section

If installDCV is Yes

  • DCVwebConsole : DCV web browser client URL. Native DCV clients can be downloaded from https://www.amazondcv.com/. Login as the user specified in Description field.

If installWebmin is Yes

  • WebminUrl : Webmin URL link. Set the root password by running sudo passwd root using EC2instanceConnect, SSMsessionManager or SSH session first

If enableALB is Yes

  • AlbConsole: ALB console URL
  • AlbDnsName: ALB domain name. Create a DNS CNAME or Route 53 alias to ALB domain name especially if you are using HTTPS listener

If enableCloudFront is Yes

  • CloudFrontConsole : CloudFront console URL link
  • CloudFrontURL : CloudFront distribution URL, e.g. https://d111111abcdef8.cloudfront.net

Troubleshooting

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

PHP performance configuration

Based on public articles about PHP performance (many thanks to the authors), the following enhancements were made:

Obtaining certificate for HTTPS

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.

Certbot prerequisites

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.

Using apache plugin

  • From terminal, run the below command and follow instructions.
    sudo certbot --apache
    

Using nginx plugin

  • 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

Using certbot-dns-route53 plugin

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.

Using Cloudwatch agent

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

Create agent configuration file. You can use agent configuration file wizard:

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

Start Cloudwatch agent

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.

Compiling PHP extensions on Amazon Linux 2023 (AL2023)

If you are looking to compile PHP extensions on AL2023, refer to community article How do I compile PHP extensions on Amazon Linux 2023?

About EC2 instance

Well-architected

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:

Restoring from backup

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

Securing

To futher secure your EC2 instance, you may want to

Clean Up

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

Security

See CONTRIBUTING for more information.

License

This library is licensed under the MIT-0 License. See the LICENSE file.