Level 200: CloudFront with WAF Protection: Lab Guide


  • Ben Potter, Security Lead, Well-Architected

Table of Contents

  1. Launch Instance
  2. Configure WAF
  3. Configure CloudFront
  4. Tear Down

1. Launch Instance

You can launch a Linux instance using the AWS Management Console. This tutorial is intended to help you launch your first instance quickly, so it doesn't cover all possible options. For more information about the advanced options, see Launching an Instance. Launch an instance:

  1. Open the Amazon EC2 console at https://console.aws.amazon.com/ec2/.
  2. From the console dashboard, choose Launch Instance. ec2-launch-wizard
  3. The choose an Amazon Machine Image (AMI) page displays a list of basic configurations, called Amazon Machine Images (AMIs), that serve as templates for your instance. Select the HVM edition of the Amazon Linux AMI, either version. ec2-launch-wizard
  4. On the Choose an Instance Type page, you can select the hardware configuration of your instance. Select the t2.micro type, which is selected by default. Notice that this instance type is eligible for the free tier. Then select Next: Configure Instance Details. ec2-launch-wizard
  5. On the Configure Instance Details page, make the following changes:

    5.1 Select Create new IAM role.


    5.2 In the new tab that opens, select Create role.


    5.3 With AWS service pre-selected, select EC2 from the top of the list, then click Next: Permissions.


    5.4 Enter s3 in the search and select AmazonS3ReadOnlyAccess from the list of policies, then click Next: Review. This policy will give this EC2 instance access to read and list any objects in Amazon S3 within your AWS account.


    5.5 Enter a role name, such as ec2-s3-read-only-role, and then click Create role.


    5.6 Back on the EC2 launch web browser tab, select the refresh button next to Create new IAM role, and click the role you just created.


    5.7 Scroll down and expand the Advanced Details section. Enter the following in the User Data test box to automatically install Apache web server and apply basic configuration when the instance is launched:

yum update -y
yum install -y httpd
service httpd start
chkconfig httpd on
groupadd www
usermod -a -G www ec2-user
chown -R root:www /var/www
chmod 2775 /var/www
find /var/www -type d -exec chmod 2775 {} +
find /var/www -type f -exec chmod 0664 {} +
  1. Accept defaults and click Next: Add tags.
  2. Click Next: Configure Security Group. 7.1 Accept default option Create a new security group. 7.2 On the line of the first default entry SSH, select Source as My IP. 7.3 Click Add Rule, select Type as HTTP and Source as Anywhere. Note that best practice is to have an Elastic Load Balancer inline or the EC2 instance not directly exposed to the internet. However, for simplicity in this lab, we are opening the access to anywhere. Other lab modules secure access with Elastic Load Balancer.

    Security Group

    7.5 Click Review and Launch.


  3. On the Review Instance Launch page, check the details, and then click Launch.

  4. If you do not have an existing key pair for access instances, a prompt will appear. Click Create New,then type a name such as lab, click Download Key Pair, and then click Launch Instances.



This is the only chance to save the private key file. You'll need to provide the name of your key pair when you launch an instance, and you'll provide the corresponding private key each time you connect to the instance.
  1. Click View Instances.
  2. When your instance is launched, its status will change to running, and it will need a few minutes to apply patches and install Apache web server.


  1. You can connect to the Apache test page by entering the public DNS, which you can find on the description tab or instances list. Take note of this public DNS value.

2. Configure AWS WAF

Using AWS CloudFormation, we are going to deploy a basic example AWS WAF configuration for use with CloudFront.

  1. Sign in to the AWS Management Console, select your preferred region, and open the CloudFormation console at https://console.aws.amazon.com/cloudformation/. Note if your CloudFormation console does not look the same, you can enable the redesigned console by clicking New Console in the CloudFormation menu.
  2. Click Create stack.


  1. Enter the following Amazon S3 URL: https://s3-us-west-2.amazonaws.com/aws-well-architected-labs/Security/Code/waf-global.yaml and click Next.


  1. Enter the following details:
  2. Stack name: The name of this stack. For this lab, use waf.
  3. WAFName: Enter the base name to be used for resource and export names for this stack. For this lab, you can use Lab1.
  4. WAFCloudWatchPrefix: Enter the name of the CloudWatch prefix to use for each rule using alphanumeric characters only. For this lab, you can use Lab1. The remainder of the parameters can be left as defaults.


  1. At the bottom of the page click Next.
  2. In this lab, we won't add any tags or other options. Click Next. Tags, which are key-value pairs, can help you identify your stacks. For more information, see Adding Tags to Your AWS CloudFormation Stack.
  3. Review the information for the stack. When you're satisfied with the configuration, click Create stack.
  4. After a few minutes the stack status should change from CREATE_IN_PROGRESS to CREATE_COMPLETE.
  5. You have now set up a basic AWS WAF configuration ready for CloudFront to use!

3. Configure Amazon CloudFront

Using the AWS Management Console, we will create a CloudFront distribution, and link it to the AWS WAF ACL we previously created.

  1. Open the Amazon CloudFront console at https://console.aws.amazon.com/cloudfront/home.
  2. From the console dashboard, choose Create Distribution.


  1. Click Get Started in the Web section.


  1. Specify the following settings for the distribution:
  2. In Origin Domain Name enter the EC2 public DNS name you recorded from your instance launch.


  • In the distribution Settings section, click AWS WAF Web ACL, and select the one you created previously.



  1. When your distribution is deployed, confirm that you can access your content using your new CloudFront URL or CNAME. Copy the Domain Name into a web browser to test.


For more information, see Testing a Web Distribution in the CloudFront documentation. 7. You have now configured Amazon CloudFront with basic settings and AWS WAF.

For more information on configuring CloudFront, see Viewing and Updating CloudFront Distributions in the CloudFront documentation.

3. Tear down this lab

The following instructions will remove the resources that have a cost for running them. Please note that Security Groups and SSH key will exist. You may remove these also or leave for future use.

Delete the CloudFront distribution:

  1. Open the Amazon CloudFront console at https://console.aws.amazon.com/cloudfront/home.
  2. From the console dashboard, select the distribution you created earlier and click the Disable button. To confirm, click the Yes, Disable button.
  3. After approximately 15 minutes when the status is Deployed, select the distribution and click the Delete button, and then to confirm click the Yes, Delete button.

Delete the AWS WAF stack: 1. Sign in to the AWS Management Console, and open the CloudFormation console at https://console.aws.amazon.com/cloudformation/. 2. Select the waf-cloudfront stack. 3. Click the Actions button, and then click Delete Stack. 4. Confirm the stack, and then click the Yes, Delete button.

References & useful resources

Amazon Elastic Compute Cloud User Guide for Linux Instances Amazon CloudFront Developer Guide Tutorial: Configure Apache Web Server on Amazon Linux 2 to Use SSL/TLS AWS WAF, AWS Firewall Manager, and AWS Shield Advanced Developer Guide


Licensed under the Apache 2.0 and MITnoAttr License.

Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at


or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.