Now all need websites for everything like business, education, government, non-profit, and many more. Creating a website can use a virtual machine, a container, serverless, or many other technologies. For this tutorial, I use containers when creating a website because containers can run on-premises or through cloud providers.
The reader will learn how to create a web application firewall with AWS WAF and AWS App Runner as a web application. AWS App Runner is an AWS service that deploys web applications or API using Amazon ECR or GitHub only. While AWS WAF (Web Application Firewall) is an AWS service that can protect the web application.
Requirements
Before getting started with this tutorial, you need:
- an AWS account.
- Terraform.
- your IDE.
- use my repository for example.
- My blog about Amazon ECR on this link.
Implementing AWS App Runner with Terraform
You are learning how to create an IAM role, push an image to Amazon ECR and create an AWS service using Terraform (for this tutorial, you create AWS App Runner service).
AWS IAM (Identity and Access Management) & Amazon ECR (Elastic Container Registry)
AWS IAM (Identity and Access Management) is an AWS service that gives users access to other AWS services. I need an IAM role because I need permission from AWS App Runner to Amazon ECR image.
Create an IAM role for the AWS App Runner service that can access Amazon ECR images. But I need a trust policy because when I choose AWS service, AWS App Runner is not available. Choose custom trust policy and copy this trust policy for AWS App Runner:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "build.apprunner.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Then click Next for the next step. This next step is to add a permission policy with copy AWSAppRunnerServicePolicyForECRAccess
. This permission policy is used because it needs permission from AWS App Runner to the Amazon ECR image.
Then click Next again. Fill in the IAM role name AppRunnerECRAccessRole
and click Create role.
After creating an IAM role, you can see the IAM role already created. Click View role and click copy arn:aws:iam::YOUR_AWS_ACCOUNT:role/service-role/AppRunnerECRAccessRole
. This IAM role is used when creating the AWS App Runner service because authentication configuration is required.
Open your IDE. Clone my repository with the command git clone https://github.com/budionosan/helloworld.git
, then open the helloworld
folder with the command cd helloworld
.
git clone https://github.com/budionosan/helloworld.git
cd helloworld
Then navigate to Amazon ECR. You can read how to create a repository and push images to Amazon ECR.
NOTE: After create ECR repository, you can click View push commands. After pushing the image to Amazon ECR, you can check ECR repository.
Click your repository name and click Copy URI. This ECR image is used when creating the AWS App Runner service because it uses container images.
AWS App Runner
Back to the IDE environment with command the cd ..
. Create a folder called apprunnerxwaf
with the command mkdir apprunnerxwaf
, then navigate to the apprunnerxwaf
folder with the command cd apprunnerxwaf
.
cd ..
mkdir apprunnerxwaf
cd apprunnerxwaf
Install Terraform on this link in your IDE. Terraform is available on Windows, Linux, macOS, and many other platforms. After installing Terraform, check the Terraform version with the command terraform --version
for whether Terraform is already installed or not.
Create a Terraform file to create an AWS App Runner service in your IDE:
The source code of the Terraform file can be seen on the link.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "4.61.0"
}
}
}
required_providers
means cloud provider name such as AWS, Google Cloud, Azure, or other cloud providers. For this tutorial, I chose AWS because I want to create an AWS App Runner service. You can see Terraform on the AWS latest version on this link.
provider "aws" {
region = "us-west-2"
}
providers “aws”
means the AWS region for creating AWS resources, for example “us-west-2” (Oregon) or "us-east-1" (North Virginia).
resource "aws_apprunner_service" "apprunnerxwaf" {
resource "aws_apprunner_service"
means Terraform for AWS App Runner service.
service_name = "apprunnerxwaf"
service_name
means AWS App Runner service name.
source_configuration {
authentication_configuration {
access_role_arn = "arn:aws:iam::YOUR_AWS_ACCOUNT:role/service-role/AppRunnerECRAccessRole"
}
access_role_arn
means your IAM Role for AWS App Runner can access Amazon ECR that already created, example AppRunnerECRAccessRole
.
image_repository {
image_configuration {
port = "8080"
}
image_identifier = "YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/ECR_REPOSITORY_NAME:latest"
image_configuration
means port listen while image_identifier
means your Amazon ECR image URL that already created.
NOTE: Change YOUR_AWS_ACCOUNT
with your AWS account ID 12 digits (example: 098765432123) and also ECR_REPOSITORY_NAME
with your Amazon ECR repository name.
image_repository_type = "ECR"
}
auto_deployments_enabled = false
}
tags = {
Name = "apprunnerxwaf"
}
}
image_repository_type
means ECR (private) or ECR_PUBLIC (public) while auto_deployments_enabled
means enable automatic deployment with CI/CD (true) and disable automatic deployment (false).
Initialize the Terraform file with the command
terraform init
terraform init
means install cloud provider plugin (for this tutorial, AWS). If initializing this Terraform file is successful, show notifications below this screenshot. But if initializing the Terraform file is not successful, check your Terraform file typo.
Apply the Terraform file with the command
terraform apply
terraform apply
means create cloud provider services (for this tutorial, create AWS App Runner service).
Enter yes
in the prompt above to create the AWS App Runner service. After entering yes
, Terraform will create an App Runner service.
Navigate to AWS App Runner to check the service. The service name apprunnerxwaf is running. The default domain has been managed by AWS, but you can customize this default domain to your domain.
Click the default domain URL, which automatically opens a new tab as shown below:
Implementing AWS WAF CAPTCHA
You are learning how to create a web ACL and rule of web ACL using CAPTCHA based statements.
AWS WAF (Web Application Firewall)
For the website to be safe from attackers, I must focus on security to protect the website. I use security features such as CAPTCHA. CAPTCHA is a security feature that must be solved by a real human (not a bot) before entering the website. Navigate to AWS WAF.
I use AWS WAF to add CAPTCHA features to the AWS App Runner service. AWS WAF is integrated with AWS services such as:
- Amazon API Gateway
- Application Load Balancer (used in Amazon EC2, Amazon ECS, Amazon EKS and AWS Fargate)
- AWS AppSync
- AWS App Runner
- Amazon Cognito
- Amazon CloudFront
Click Create web ACL. Fill in the web ACL name, description, and CloudWatch metric name (for this tutorial, I don't use CloudWatch because the focus is on AWS WAF only). Choose regional resources because I want to be integrated with AWS App Runner. Choose US West (Oregon) for the region and click Next.
Click add rules. Add rules in two ways: managed rule groups or my own rules. My own rules means I can create them as needed while managed rule groups means rule groups are managed by AWS and another company. Choose Add my own rules and rule groups.
Choose rule builder. The rule builder can customize the rules of the web ACL. To be able to use AWS WAF integrated with AWS App Runner, I have a rule: if a user from Indonesia accesses the web application of AWS App Runner, then the user must pass CAPTCHA for access. If a user is from another country, the user can access the web application without needing to pass the CAPTCHA.
Fill in the rule name. The statement rule has an option:
matches the statement. Example IF a request has statement
X
THEN actionY
but IF a request has the statementA
, actionY
can not run.matches all the statements. Example IF a request has statements
X1
ANDX2
, THEN actionY
can be run, but IF a request has a statementX1
only, actionY
cannot be run.matches at least one of the statements. Example IF a request has statement
X1
ORX2
THEN actionY
but IF a request has a statementX1
only, actionY
still can run.doesn’t match the statement. Example IF a request does not match the statement
X
THEN actionY
but IF a request has the statementA
, actionY
can run.
Choose matches the statement. The statement has options to inspect such as country, IP address, label, etc. For this tutorial, use the country option to test whether WAF is running or not. Choose country codes. In this example, choose Indonesia - ID (you can change your country) that is based on the source IP address.
The rule has action options:
- Allow: The user can access the web application if the request matches the statement rule.
- Block: The user cannot access the web application, and the web application is not available or responding if the request does not match the statement rule.
- Count: The user does not have an effect when accessing the web application because this action is counting requests only.
- CAPTCHA: The user can access the web application if the user can pass the CAPTCHA.
- Challenge: The user can access the web application if the user must enable JavaScript to verify that you are a human (not a bot). If the user does not enable JavaScript, the web application can't be accessed until JavaScript is enabled.
Choose CAPTCHA for an action in the rule. Click add rule and you can see the rule is already created.
The default action is to take action if the request doesn't match the statement rule. This condition can be explained:
- Allow: if you are from another country (except Indonesia) and want to access the web application, you can access the web application without passing the CAPTCHA.
- Block: if you are from another country (except Indonesia) and want to access the web application, you cannot access the web application.
For this article, the default action is allow and click Next.
Because only one rule, steps 3 and 4 are skipped. Click Next. Step 5 is to scroll down and click Create web ACL.
Click the web ACL name.
Then click add AWS resources.
Choose the Amazon App Runner service and choose the App Runner service name. Click add to enable integration with AWS WAF.
Then go to rules and click the rule name.
This role explains that if a request matches the statement (in this case, the request option from the country is Indonesia), the next action after the request match is CAPTCHA.
Navigate again to AWS App Runner for testing the web application with WAF. When you open the URL link, see the available page that needs a CAPTCHA to confirm you are a human (not a bot). Click Begin for the next step.
NOTE: If your web application is not like the above screenshot, you can click refresh because the web application needs time.
You must solve the CAPTCHA with a puzzle type like this screenshot. This puzzle type must match top and bottom and become one with a slider. Click Submit.
After you pass the CAPTCHA, you can access the web application of AWS App Runner.
Conclusion
In this tutorial, you already learned how to push images to Amazon ECR. Amazon ECR is an AWS service that is very useful for storing your container images and can be used with other AWS services such as AWS App Runner. You can get started learning containers by learning AWS App Runner. You also already know how to create AWS services using Terraform as an Infrastructure as Code (IaC) and how to use AWS WAF to integrate with AWS App Runner as a web application to protect from anywhere attacks.
Top comments (1)
Using WAF nowadays has to be a priority and not just an option in our developments, great summary