CertNote/ Commute Study Notes
Roadmap
KOEN
CLF-C02 · FoundationalCloud Practitioner - Foundational
DVA-C02 · AssociateDeveloper - Associate
SAA-C03 · AssociateSolutions Architect - Associate
SOA-C02 · AssociateCloudOps Engineer - Associate
SAP-C02 · ProfessionalSolutions Architect - Professional
DOP-C02 · ProfessionalDevOps Engineer - Professional
  • Week 1
    • 1.DevOps as an Operating Model: The Five Axes of CALMS and the Truth DORA Proved Through Measurement
    • 2.Well-Architected Framework: Rereading It Through the Six Lenses of DevOps
    • 3.The AWS DevOps Tool Map: The Code* Series and the Real Picture Beyond It
    • 4.Multi-Account Strategy: The Real Picture of Organizations, Control Tower, and IAM Identity Center
    • 5.Week 1 Wrap-Up: Cementing the DevOps Thinking Frame with Scenarios
  • Week 2
  • Week 3
  • Week 4
  • Week 5
  • Week 6
    • 1.ECR: Solving the Problems that Container Image Registries Must Solve
    • 2.ECS Automated Deployment: From Task Definition Updates to Auto Scaling
    • 3.EKS CI/CD: Why GitOps Was Born, and How ArgoCD and Flux Changed Kubernetes
    • 4.App Runner and ECS Copilot: The Spectrum of Container Operations Abstraction
    • 5.Week 6 Review + 12 Scenario Practice Problems
  • Week 7
  • Week 8
  • Week 9
  • Week 10
  • Week 11
  • Week 12
  • Week 13
  • Week 14
  • Week 15
  • Week 16
Linux Master 2 · 2급KAIT Linux Master - Level 2
SCS-C03 · SpecialtySecurity - Specialty
Linux Master 1 · 1급KAIT Linux Master - Level 1
MLA-C01 · AssociateMachine Learning Engineer - Associate
AIF-C01 · FoundationalAI Practitioner - Foundational
DEA-C01 · AssociateData Engineer - Associate
MLS-C01 · SpecialtyMachine Learning - Specialty
SQLD · 개발자SQL Developer (SQLD)

© CertNote · 주간랩스

  • About
  • Changelog
  • Contact
  • Terms
  • Privacy
← DOP-C02/Week 6/Day 4

Based on the DOP-C02 exam guide·Report an error

DOP-C02· ProWeek 6 · Day 4~28 min read

Day 4 - App Runner and ECS Copilot: The Spectrum of Container Operations Abstraction

ECS and EKS are powerful but operationally complex. Task Definition, Service, ALB Target Group, Security Group, IAM Role—running one ECS service properly requires managing dozens of AWS resources. Does a startup or small team need all this for a single web API?

App Runner answers "no." "Give me source code or image; I handle the rest"—builds, deployment, load balancing, SSL, auto-scaling, monitoring—AWS completely manages. ECS Copilot is the middle ground: keep full ECS control while hiding complex resource configuration behind CLI abstraction.

Today we understand the abstraction spectrum and develop exam ability to immediately judge "which service for which situation?"

💡 Related Theory: Container service abstraction spectrum applies infrastructure software engineering's abstraction layer concept. Low level (EKS EC2) provides maximum control and maximum complexity; high level (App Runner) provides minimum control and minimum complexity. "Good level" doesn't exist—"appropriate level for requirements" is the selection criterion. Like Unix philosophy's "single tools doing one thing well in combination," AWS container services provide layered abstraction levels where users choose appropriate layer.

AWS App Runner: "You Deploy, We Handle Everything"

App Runner, launched 2021, is fully-managed container PaaS (Platform-as-a-Service). Developers point to Dockerfile or source code; App Runner handles building (source-based), running images, HTTPS endpoint creation, auto-scaling configuration automatically.

Two Source Types:

First, ECR image-based. Already-built container images pulled directly from ECR and executed. CI/CD pipeline builds images and pushes to ECR; App Runner detects new image and auto-deploys.

Second, GitHub source-based. Point to GitHub repository; App Runner builds directly in internal build system. Deployment defined via apprunner.yaml.

Source TypePullBuild Provider
ECR PrivateImage directlyExternal CI/CD
ECR PublicImage directlyExternal CI/CD
GitHubSource codeApp Runner internal
# Create App Runner Service from ECR image
aws apprunner create-service \
  --service-name checkout-api \
  --source-configuration '{
    "ImageRepository": {
      "ImageIdentifier": "111.dkr.ecr.ap-northeast-2.amazonaws.com/checkout:latest",
      "ImageRepositoryType": "ECR",
      "ImageConfiguration": {
        "Port": "8080",
        "RuntimeEnvironmentVariables": {"LOG_LEVEL": "INFO"},
        "RuntimeEnvironmentSecrets": {
          "DB_PASSWORD": "arn:aws:secretsmanager:ap-northeast-2:111:secret:prod/checkout/db"
        }
      }
    },
    "AutoDeploymentsEnabled": true,
    "AuthenticationConfiguration": {
      "AccessRoleArn": "arn:aws:iam::111:role/AppRunnerECRAccessRole"
    }
  }' \
  --instance-configuration '{
    "Cpu": "1 vCPU",
    "Memory": "2 GB",
    "InstanceRoleArn": "arn:aws:iam::111:role/AppRunnerInstanceRole"
  }' \
  --auto-scaling-configuration-arn "arn:aws:apprunner:ap-northeast-2:111:autoscalingconfiguration/standard/1/..."

AutoDeploymentsEnabled: true is key. Every time new image is pushed to ECR, App Runner auto-triggers Rolling update. No CodePipeline needed—"ECR push → auto-deploy" is possible.

Two Role Distinction:

AuthenticationConfiguration.AccessRoleArn: App Runner service itself uses this Role pulling images from ECR. build.apprunner.amazonaws.com assumes this Role. Use AWSAppRunnerServicePolicyForECRAccess managed policy.

InstanceConfiguration.InstanceRoleArn: Container application code uses this Role calling AWS APIs. S3 access, Secrets Manager reads, DynamoDB queries, etc. require permissions granted to this role. ECS's Task Role equivalent.

💡 Related Theory: App Runner's two-Role distinction is identical to ECS's Task Execution Role vs Task Role pattern. "Service pulling images" permission (AccessRole = Task Execution Role) and "application accessing AWS services" permission (InstanceRole = Task Role) are separated. This separation implements least privilege principle—image pull permission doesn't automatically grant DynamoDB access, and DynamoDB permission doesn't automatically grant ECR cross-image pull.

App Runner Auto Scaling: MaxConcurrency-Based

App Runner's auto-scaling differs from ECS Fargate's CPU/memory-based. MaxConcurrency—maximum simultaneous requests per instance—is the scaling basis.

# Create auto-scaling configuration
aws apprunner create-auto-scaling-configuration \
  --auto-scaling-configuration-name high-concurrency \
  --max-concurrency 100 \
  --max-size 25 \
  --min-size 2

Operation: When total simultaneous requests across all running instances approaches MaxConcurrency × instance count, new instances start. With MaxConcurrency=100 and 2 running instances, hitting 200 concurrent requests triggers scale-out.

Setting min-size=0 scales to 0 instances when no traffic—cost becomes $0, but first request experiences Cold Start. min-size=1 always keeps minimum instance ready, eliminating Cold Start.

🔍 Deep Dive: App Runner's MaxConcurrency-based scaling specializes in "concurrency." Web APIs can have low CPU yet high latency with many simultaneous requests—50% CPU handling 1000 concurrent requests means each request has long response time. MaxConcurrency uses this latency increase as scaling signal. I/O-bound workloads like Go goroutine or Node.js event loop make concurrency more important than CPU. App Runner selecting MaxConcurrency as primary metric reflects web API workload characteristics.

App Runner VPC Integration: Connector and Private Ingress

Initial App Runner was internet-only isolated from VPC. Two features overcome this:

VPC Connector (Outbound):

Enables App Runner instances to outbound-connect to VPC resources (RDS, ElastiCache, internal services). App Runner → VPC direction. Inbound from VPC to App Runner still needs public internet endpoint (without Private Ingress).

# Create VPC Connector
VPC_CONNECTOR_ARN=$(aws apprunner create-vpc-connector \
  --vpc-connector-name checkout-vpc-connector \
  --subnets subnet-private-1 subnet-private-2 \
  --security-groups sg-apprunner-access \
  --query 'VpcConnector.VpcConnectorArn' --output text)
 
# Attach VPC Connector to Service
aws apprunner update-service \
  --service-arn arn:aws:apprunner:...:service/checkout-api \
  --network-configuration "{
    \"EgressConfiguration\": {
      \"EgressType\": \"VPC\",
      \"VpcConnectorArn\": \"${VPC_CONNECTOR_ARN}\"
    }
  }"

Private Ingress (Inbound, 2023+):

Restrict App Runner Service access to VPC internals only. VPC Endpoint + VPC Ingress Connection configured. Suitable for internal microservices requiring no public internet endpoint.

# Create VPC Ingress Connection
aws apprunner create-vpc-ingress-connection \
  --service-arn arn:aws:apprunner:...:service/checkout-api \
  --vpc-ingress-connection-name checkout-private-ingress \
  --ingress-vpc-configuration '{
    "VpcId": "vpc-abc123",
    "VpcEndpointId": "vpce-xyz456"
  }'

⚠️ Trap: App Runner VPC Connector is unidirectional outbound only. VPC Connector enables App Runner → VPC, not VPC → App Runner. Even with VPC Connector, VPC internal servers can't directly HTTP-request App Runner Service—they access through public internet endpoint (Private Ingress required for private access). Private Ingress configuration lets VPC Endpoint access; public endpoint must disable—choose one.

App Runner vs ECS Fargate vs EKS: Abstraction Level Selection Criteria

CriterionApp RunnerECS FargateEKS
Abstraction LevelHighestMiddleLowest
Setup TimeMinutesHoursDays
CustomizationLimitedRichUnlimited
Cost (small scale)Cheap (usage-based)MiddleExpensive (control plane $73/month)
Non-HTTP WorkloadsNot supportedSupportedSupported
VPC IntegrationVPC Connector (outbound)Full integrationFull integration
Scaling MetricMaxConcurrencyCPU/memory/ALB RPSHPA (CPU/memory/custom)
Suitable WorkloadSimple web APIGeneral containersComplex microservices, ML, Stateful
Blue/Green DeploymentBuilt-in (automatic)CodeDeploy requiredArgoCD/Flux

Exam selection criteria:

  • "Simple web API, minimal operations, fast launch" → App Runner
  • "Complex communication, policy, Stateful, non-HTTP protocol" → EKS
  • "Full ECS control, relatively simple deployment" → ECS Fargate
  • "No auto-scaling needed, most simple, fixed-price" → Lightsail Containers (frequently exam trap answer; lacks auto-scaling)

📚 Case Study: Notion's App Runner adoption. 2022, Notion migrated internal microservices to App Runner. Reason: small teams consumed time with ECS complexity (Task Definition revision management, ALB rule, Target Group connection). Post App Runner, new microservice deployment time shortened from 1-2 days to 1-2 hours. However, complex service mesh and sidecar-requiring services remained on EKS—App Runner supports single container only.

ECS Copilot CLI: ECS's User-Friendly Abstraction

ECS Copilot (2020 GA), AWS open-source CLI tool, defines entire ECS environment via Manifest file and deploys via CLI commands. Internally generates and manages CloudFormation.

# App initialization (Organizations/App level)
copilot app init my-store
 
# Add environment (VPC, ECS cluster auto-created)
copilot env init --name prod --profile prod-aws-profile
 
# Add service (ALB, ECS Service, Task Definition auto-created)
copilot svc init \
  --svc-type "Load Balanced Web Service" \
  --name api \
  --dockerfile ./Dockerfile
 
# Deploy
copilot svc deploy --name api --env prod
 
# Auto-generate pipeline (CodePipeline + CodeBuild)
copilot pipeline init
copilot pipeline deploy

Manifest File (copilot/api/manifest.yml):

name: api
type: Load Balanced Web Service
 
image:
  build: Dockerfile
  port: 8080
 
http:
  path: '/'
  healthcheck: '/health'
 
cpu: 256
memory: 512
count: 2  # Or count: {range: 2-10, cpu_percentage: 70} (Auto Scaling)
 
network:
  vpc:
    placement: 'private'
 
secrets:
  DB_PASSWORD: /myapp/prod/db-pass  # SSM Parameter Store
 
storage:
  databases:
    - name: orders
      engine: PostgreSQL  # Aurora Serverless auto-created + connected

Copilot auto-creates:

  • VPC (subnets, Internet Gateway, NAT Gateway)
  • ECS cluster
  • ALB + Target Group + Listener Rule
  • ECS Service + Task Definition
  • CloudWatch Log Group
  • IAM Roles (Task Execution Role + Task Role)
  • Security Groups
  • CodePipeline + CodeBuild (pipeline init execution)

🔍 Deep Dive: Copilot's internals resemble AWS CDK—"Infrastructure as Intent" pattern. Developers declare "this service is HTTP API running port 8080 intent"; Copilot generates concrete CloudFormation resources achieving this intent. CDK uses TypeScript for infrastructure; Copilot uses YAML Manifest. Key difference: Copilot specializes in "ECS service deployment"—specific domain gives simpler code than generic tools (CDK, Terraform) for ECS.

Copilot Pipeline structure:

GitHub main push
    ↓
CodePipeline (created by copilot pipeline deploy)
    ↓
CodeBuild (docker build + copilot svc deploy)
    ├── staging deployment (manual approval)
    └── production deployment

copilot/pipelines/*/manifest.yml:

name: my-store-pipeline
version: 1
source:
  provider: GitHub
  properties:
    branch: main
    repository: https://github.com/my-org/my-store
stages:
  - name: test
    test_commands:
      - make test
  - name: prod
    requires_approval: true

💡 Related Theory: ECS Copilot's Manifest approach is declarative deployment implementation. Declare "what you want" (final state); tool determines "how to achieve it" (procedure). Kubernetes YAML manifests follow same philosophy. Opposite is imperative deployment—step-by-step API calls (aws ecs create-service, aws elbv2 create-listener). Declarative approach automatically computes difference between current state and desired state, applying only necessary changes. Copilot using CloudFormation internally—CloudFormation itself is declarative IaC tool—explains why.

App Runner Monitoring and Observability

App Runner auto-integrates CloudWatch and X-Ray.

CloudWatch Metrics (auto-collected):

  • ActiveInstances: currently running instances
  • RequestLatency: response time (P50, P75, P99)
  • 4xxStatusRate, 5xxStatusRate: HTTP error rate
  • HttpRequestCount: total requests

X-Ray integration:

aws apprunner update-service \
  --service-arn arn:aws:apprunner:...:service/checkout-api \
  --observability-configuration '{
    "ObservabilityEnabled": true,
    "ObservabilityConfigurationArn": "arn:aws:apprunner:...:observabilityconfiguration/DefaultConfiguration"
  }'

CloudWatch Logs:

  • /aws/apprunner/<service>/<id>/application: application logs (stdout/stderr)
  • /aws/apprunner/<service>/<id>/system: App Runner system logs (deployment, scaling)

🎯 Scenario: Startup launching first web API. 3-person team, no infrastructure expert. Requirements: (1) fast deployment, (2) auto-scale on traffic, (3) automatic HTTPS, (4) PostgreSQL database. Options: ECS Fargate (requires Task Definition, ALB, Target Group, Security Group configuration), App Runner (point to image; auto-handle rest). Choice: App Runner + VPC Connector for RDS access. ECR image push auto-deploys. MaxConcurrency=50 for scaling. HTTPS automatic. Six months later, team grows and complex microservice architecture needed; Copilot-based ECS Fargate transition and finer control adoption becomes natural evolutionary path.

App2Container: Containerizing Legacy Apps

App2Container automates containerization of Java/.NET applications running on EC2 or on-premises servers. Analyzes running server processes, auto-generating Dockerfile and ECS/EKS deployment configuration.

# App2Container analysis (runs on application server)
sudo app2container analyze --application-id java-app-1234
 
# Containerize + ECR Push
sudo app2container containerize --application-id java-app-1234
 
# Generate ECS Task Definition + CloudFormation
sudo app2container generate app-deployment --application-id java-app-1234

On exam, "on-premises Java app container migration" keyword → App2Container is answer.

Summary

App Runner is optimal for "simple web API + minimal operations." AutoDeploymentsEnabled provides ECR push auto-deploy; MaxConcurrency-based auto-scaling; VPC Connector for RDS access. Two-Role separation (AccessRole = ECR pull, InstanceRole = app AWS API) implements least privilege.

ECS Copilot abstracts ECS Fargate's CloudFormation complexity behind Manifest YAML. Prefix copilot pipeline deploy generates CodePipeline. Can directly modify Copilot-generated CloudFormation stacks.

Selection: "HTTP API + minimal operations" → App Runner. "ECS + simple config" → Copilot. "Complex orchestration, sidecars, service mesh" → EKS. Lightsail Containers lack auto-scaling—frequent exam trap answer.

📝 Practice Questions

Click a choice to reveal the answer and explanation.

Question 1

Which service is most appropriate for the scenario "a simple web API, a team of 3, no infrastructure expert, automatic scaling required"?

Question 2

How do you configure an App Runner service to deploy automatically when a new image is pushed to ECR?

Question 3

What configuration is needed to access an RDS PostgreSQL database inside a VPC from App Runner?

Question 4

What is the key difference between App Runner auto scaling and ECS Fargate?

Question 5

What does copilot pipeline init of the ECS Copilot CLI create automatically?

Question 6

What is the difference between the App Runner AccessRole and InstanceRole?

Question 7

Which AWS service migrates "a Java application running on an on-premises server to ECS Fargate with minimal code changes"?

PreviousEKS CI/CD: Why GitOps Was Born, and How ArgoCD and Flux Changed KubernetesWeek 6 · Day 3Next Week 6 Review + 12 Scenario Practice ProblemsWeek 6 · Day 5

Official references

  • DOP-C02 official exam page(opens in a new tab)
  • Amazon ECS · Fargate documentation(opens in a new tab)
  • Amazon VPC documentation(opens in a new tab)
  • Amazon EKS documentation(opens in a new tab)
  • AWS CloudFormation documentation(opens in a new tab)
  • Elastic Load Balancing documentation(opens in a new tab)

On this page

  • AWS App Runner: "You Deploy, We Handle Everything"
  • App Runner Auto Scaling: MaxConcurrency-Based
  • App Runner VPC Integration: Connector and Private Ingress
  • App Runner vs ECS Fargate vs EKS: Abstraction Level Selection Criteria
  • ECS Copilot CLI: ECS's User-Friendly Abstraction
  • App Runner Monitoring and Observability
  • App2Container: Containerizing Legacy Apps
  • Summary
  • Practice Questions