Platform

AWS Web Service Infrastructure and Operations Model

A connected view of Route 53, IAM, EC2, S3, CloudFront, ELB, Auto Scaling, and CloudWatch as a web service request flow.

AWS Web Service Infrastructure and Operations Model

When first studying AWS, it is easy to organize it into services such as EC2, S3, IAM, and Route 53. However, when you try to configure an actual web service, the request flow is visible before the service name. Users connect to a domain, and DNS determines which endpoint to send the traffic to. Static files can be placed in S3, but security and caching strategies vary depending on whether you open the S3 URL directly to the user or use CloudFront in front of it. The backend server can be exposed directly to EC2, but usually it should be placed behind the ALB and health checks and scaling standards should be set together.

This article is a record of Route 53, IAM, EC2, EBS, S3, CloudFront, ELB, Auto Scaling, and CloudWatch reorganized into one web service infrastructure flow. Rather than memorizing each function, we focused on connecting the path through which requests pass and the points that need to be checked during operation.

1. Request flow originating from DNS

A domain is a name that people remember, and DNS converts that name into an actual address that can be accessed. Route 53 is a DNS service provided by AWS and creates several records within the Hosted Zone. Basically, an A record points to an IPv4 address, an AAAA record points to an IPv6 address, and a CNAME points to another domain name. Route 53 connects to EC2, ELB, S3, and CloudFront, making it the first entry point for AWS-based web services.

If it's a static website, you can point the domain to your CloudFront distribution domain, and if it's a backend API, you can point it to the ALB DNS name. In an operational environment, routing policies are more important than a simple A record. Latency based routing sends requests to a region close to the user, Weighted routing divides traffic by a specific ratio, and Geo routing selects different endpoints depending on the user's location.

In the lab, we created a Hosted Zone, added an A record to a domain like example.com, and sent traffic to a specific IP. At this time, the key point was that Hosted Zone was a container for records, and Record was a rule that determined where a specific name should be sent.

2. IAM is a boundary that must be organized before functions

Once you start creating AWS resources, you can't avoid IAM. IAM consists of User, Group, Role, and Policy. User represents an actual person or application, and Group is a group that grants the same privileges to multiple users. A role is a set of permissions that a specific subject can temporarily assume, and a policy is a JSON document that defines which operations are permitted or denied to which resources.

In the IAM exercise, I created test-iam-user, granted only AmazonEC2ReadOnlyAccess, and attempted to create an EC2 instance. The result was “no permission”. After creating a group, connecting AmazonEC2FullAccess, and adding the same user to the group, EC2 creation became possible. The important part of this exercise was not “all you need is permission,” but the flow of checking which tasks are allowed by which permissions.

When using CLI or SDK, you can create an Access Key and save it locally in .aws/credentials.

[default]
region = ap-northeast-2
aws_access_key_id = YOUR_AWS_ACCESS_KEY
aws_secret_access_key = YOUR_AWS_SECRET_KEY

However, long-term Access Keys are convenient but dangerous. It can be used in local practice, but in an operational environment, role-based access, least privilege, key rotation, and prevention of secret exposure must be considered first.

3. EC2, security group, EBS

EC2 is a service that provides virtual servers in the cloud. When creating an instance, set the AMI, instance type, key pair, security group, and storage settings. For example, select Ubuntu Server 22.04 LTS AMI, select t2.micro for free tier practice, and create a key pair for SSH connection.

In Linux/macOS, restrict key file permissions and then connect via SSH.

chmod 600 my-key.pem
ssh -i my-key.pem ubuntu@<public-ip>

Security groups act like a virtual firewall in front of EC2. Inbound rules control traffic coming into the instance from the outside, and outbound rules control traffic going out from the instance. In practice, SSH port 22 was opened, and for testing purposes, port 8000 was opened to 0.0.0.0/0. However, in an operating environment, SSH should not be opened to the public, but access IPs should be restricted or management paths such as Bastion/VPN/SSM should be reviewed.

EBS is block storage used by connecting to EC2. One EBS volume cannot be attached to multiple EC2s at the same time, but multiple EBS volumes can be attached to one EC2. EBS must be connected to EC2 within the same Availability Zone, and Snapshots can be created as backups at a specific point in time. Snapshots are stored on S3 and replicated across multiple AZs. Because of this structure, when creating a new server, a restoration strategy can be established based on AMI or Snapshot.

4. S3 static hosting and object storage

S3 is object storage. Rather than a structure that only modifies parts of the system like a file system, it stores and reads in object units. Bucket is the top-level container that holds objects, and Object is the actual file. Metadata is information about the object, and Bucket Policy defines access rights.

In the static website exercise, we created an S3 bucket, uploaded index.html, and turned on static website hosting. At this time, if you disable public access and grant s3:GetObject permission, you can read the object from outside.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}

This method is intuitive for practice, but in operation, it is more natural to put CloudFront in front rather than exposing S3 directly. If you open the S3 URL directly to the user, you need to consider TLS, caching, access control, and domain connection separately. If you put CloudFront in front, the user entry point becomes CloudFront, and S3 can focus on its role as the original storage.

You can also handle S3 with CLI.

aws s3 ls
aws s3 mb s3://your-unique-bucket-name
echo "Hello, AWS CLI!" > hello.txt
aws s3 cp hello.txt s3://your-unique-bucket-name
aws s3 rb s3://your-unique-bucket-name --force

In the SDK lab, we installed the AWS SDK for JavaScript and executed the code to create an S3 bucket and upload objects.

npm init -y
npm install --save @aws-sdk/client-s3
import { S3Client, CreateBucketCommand, PutObjectCommand } from "@aws-sdk/client-s3";

const s3Client = new S3Client({ region: "ap-northeast-2" });
const bucketName = "your-unique-bucket-name-20231010";

await s3Client.send(new CreateBucketCommand({ Bucket: bucketName }));
await s3Client.send(
  new PutObjectCommand({
    Bucket: bucketName,
    Key: "hello.txt",
    Body: "Hello, JavaScript SDK!",
  }),
);

Although the Console, CLI, and SDK are different tools, they ultimately call the same AWS API. So, if there are insufficient permissions, it will fail on the Console and also in the CLI/SDK.

5. Things that change when you put CloudFront in front

CloudFront is a CDN. It is placed in front of an origin such as S3, EC2, or ALB and caches content at an edge location close to the user. By placing your static files in S3 and connecting to CloudFront, you can handle transfer speeds, TLS, cache control, basic DDoS protection, and domain connectivity from one location.

In the CloudFront lab, we selected an S3 bucket as the origin and created Origin Access Control so that only CloudFront could read S3 objects. At this time, 'Access Denied' appears when accessing S3 directly, and it is normal to see the file when accessing the CloudFront domain.

S3 Bucket Policy restricts the CloudFront distribution ARN as a condition.

{
  "Version": "2012-10-17",
  "Statement": {
    "Sid": "AllowCloudFrontServicePrincipalReadOnly",
    "Effect": "Allow",
    "Principal": {
      "Service": "cloudfront.amazonaws.com"
    },
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::your-bucket-name/*",
    "Condition": {
      "StringEquals": {
        "AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/EXAMPLE"
      }
    }
  }
}

You can also check cache behavior by looking at the response headers in the Network tab of your browser developer tools. The first request is retrieved from Origin with x-cache: Miss from cloudfront, and subsequent requests are responded to by Edge cache with x-cache: Hit from cloudfront. If you change the file after deployment and the contents remain the same, you need to check the cache invalidation, Cache-Control header, and file name version strategy.

6. Handling server layer with ALB and Auto Scaling

Static files can be solved with S3 and CloudFront, but requests that need to be processed by the server require a computing layer. Sending traffic directly to a single EC2 device has a simple structure, but is vulnerable to failures and expansion. If you place an ALB (Application Load Balancer) in front, you can distribute traffic to multiple EC2 instances and send requests only to healthy instances with Target Group Health Check.

In the lab, two WordPress AMI-based EC2 machines were launched in different Availability Zones and registered in the ALB Target Group. When I connected to ALB DNS and refreshed, I confirmed that the requests were distributed to different instances. At this time, the Health Check path is set to /, and each target must be healthy to receive traffic normally.

Auto Scaling adjusts the number of EC2 instances according to traffic or metrics. The basic components are Launch Template, Auto Scaling Group, and Scaling Policy. Launch Template contains new instance creation information such as AMI, instance type, key pair, and security group. In ASG, specify the minimum/maximum/desired number of instances, subnet to use, and target group to connect to.

The load test was conducted with stress.

ssh -i "my-key.pem" bitnami@<public-ip>
sudo apt-get update
sudo apt-get install stress
stress --cpu 4

In CloudWatch, when CPUUtilization exceeds 80%, an alarm is generated, and a scale-out event is generated according to the target tracking policy. In the ASG Activity tab, you can see records of new instances being launched.

The most important finding here was the data inconsistency. If you run WordPress on two EC2 machines, each instance will have its own local MySQL. When ALB distributes requests, a phenomenon occurs in which some posts are visible and others are not. To scale the server layer horizontally, application instances must be made stateless and databases must be separated into an external public storage such as RDS.

7. Taking state out of the image upload service

A good example to understand EC2, S3, CloudFront, ALB, and Auto Scaling at once is the image upload service. Users upload images to a web server, and the server stores the files in S3. Subsequent images are provided through CloudFront. At this time, EC2 is only responsible for request processing and upload relay, and the final state of the file is moved to S3.

In this structure, uploaded files do not disappear even if the EC2 instance is replaced. The new instance simply faces the same S3 bucket and the same RDS. Conversely, if you save the image to the EC2 local disk, the new instance created by Auto Scaling will not have any files, and the files from the terminated instance will disappear together.

For Node.js/Express-based upload API, the flow is divided as follows.

upload request
  -> validate content type and size
  -> generate object key
  -> upload file stream to S3
  -> save metadata to RDS
  -> return image id or CloudFront URL

The S3 object key does not use the user-entered file name as is. File names may contain personal information, and names with the same name may conflict. Combining date prefix and random number ID makes it easy to set up search and organizing policies.

images/2026/07/05/9f2d6a2b-4f20-4e1a-a2fd.jpg

Applications that use the AWS SDK do not include access keys in the code. If running on EC2, use an instance profile and IAM role, and grant only the necessary S3 permissions.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject"
      ],
      "Resource": "arn:aws:s3:::example-image-bucket/images/*"
    }
  ]
}

This policy is only an example, and in actual operation, delete permission, list permission, and bucket-wide permission are reviewed separately. Giving s3:* to a server that only needs to upload makes it easier to respond to errors, but the scope of an accident increases.

If you attach CloudFront, image response will be faster, but you must also consider cache invalidation and original protection. If a user overwrites an image with the same object key, the previous image may remain in the edge cache. If possible, use an immutable key and simply save the changed image with a new key.

cache-friendly
  /images/user-1/profile/2026-07-05T10-00-00Z.jpg

cache-hostile
  /images/user-1/profile.jpg

If you make the server layer stateless, Auto Scaling becomes much safer. However, stateless does not mean “no state”; it means moving the state to the appropriate storage.

application instance
  - request handling
  - validation
  - temporary processing

external state
  - S3: uploaded files
  - RDS: relational metadata
  - ElastiCache: session or cache
  - CloudWatch Logs: runtime logs

Only with this distinction can Auto Scaling go beyond a simple server replication function and become a disaster recovery and cost control tool.

8. CloudWatch is not an after-the-fact verification tool but part of the design.

CloudWatch is a service that checks the status of AWS resources and applications through indicators and logs. You can observe EC2 CPU utilization, ALB Target status, Auto Scaling events, and Alarm status. In the lab, an Alarm was created to send an SNS email notification when CPUUtilization exceeds 80%.

During operations, it is more important to “determine in advance what indicators to look at when a problem occurs” rather than “if a problem occurs, look at CloudWatch.”

  • If the user cannot connect, check the status of Route 53, CloudFront, ALB, and Target Group.
  • If the static files do not change, check the CloudFront cache and invalidation.
  • If the server response is slow, look at ALB latency, EC2 CPU, and application logs.
  • If scaling is not possible, check CloudWatch Alarm, ASG Activity, and Launch Template errors.
  • If access is denied, look at IAM Policy, Bucket Policy, and Security Group.

Although AWS services are isolated from each other, failures usually occur along the path. Therefore, it was much more practical to organize confirmation points based on request flow rather than memorizing individual services.

Finish

The biggest remaining point from this summary is that AWS infrastructure should be viewed as a “path of requests and operations” rather than a “list of resources.” Route 53 connects names to endpoints, CloudFront caches content close to users, S3 becomes object storage, ALB divides requests into server tiers, and Auto Scaling adjusts the number of instances. IAM and security groups limit who can use the route, where, and how. CloudWatch provides signals to verify that the route is actually running.

At first, we studied each service separately, but when we look at one web service, all components are connected. DNS, cache, permissions, security groups, health check, scaling, and logs do not exist separately. When a user's request fails, it must be possible to find out where the blockage occurred. From that perspective, AWS basic services are a good starting point for understanding cloud infrastructure.

Unauthorized copying, redistribution, and automated scraping are not permitted. Please cite the original URL when referencing this article.