DevOps

AWS Core Services

Master essential AWS services: EC2 for compute, S3 for storage, IAM for access control, and VPC for networking.

By TechCoder TeamLast updated: 2026-06-02
In a Nutshell

Master essential AWS services: EC2 for compute, S3 for storage, IAM for access control, and VPC for networking. This hands-on tutorial focuses on practical implementation of aws core services concepts.

AWS Core Services

AWS core services form the foundation of cloud infrastructure. Understanding EC2, S3, IAM, and VPC is essential for any DevOps engineer.

EC2 (Elastic Compute Cloud)

Virtual servers in the cloud.

Instance Types

FamilyUse CaseExamples
TBurstable, general purposet3.micro (free tier), t3.medium
MGeneral purposem6i.large, m6g.xlarge
CCompute optimizedc6i.large, c6g.xlarge
RMemory optimizedr6i.large, r6g.xlarge
IStorage optimizedi4i.large
G/PGPU acceleratedg5.xlarge, p4d.24xlarge

Launching EC2 Instances

# Create key pair
aws ec2 create-key-pair --key-name my-key --query 'KeyMaterial' --output text > my-key.pem
chmod 400 my-key.pem

# Launch instance
aws ec2 run-instances \
  --image-id ami-0c55b159cbfafe1f0 \
  --instance-type t3.micro \
  --key-name my-key \
  --security-group-ids sg-12345678 \
  --subnet-id subnet-12345678 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-server}]'

# Describe instances
aws ec2 describe-instances --instance-ids i-1234567890abcdef0

# Start/Stop/Terminate
aws ec2 start-instances --instance-ids i-1234567890abcdef0
aws ec2 stop-instances --instance-ids i-1234567890abcdef0
aws ec2 terminate-instances --instance-ids i-1234567890abcdef0

User Data (Bootstrap Scripts)

#!/bin/bash
# Install and start nginx
yum update -y
yum install -y nginx
systemctl start nginx
systemctl enable nginx

# Install CloudWatch agent
yum install -y amazon-cloudwatch-agent
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config \
  -m ec2 \
  -s \
  -c ssm:AmazonCloudWatch-LinuxBasics

EBS Volumes

# Create volume
aws ec2 create-volume \
  --availability-zone us-east-1a \
  --size 20 \
  --volume-type gp3 \
  --encrypted \
  --kms-key-id alias/aws/ebs

# Attach volume
aws ec2 attach-volume \
  --volume-id vol-1234567890abcdef0 \
  --instance-id i-1234567890abcdef0 \
  --device /dev/xvdf

# Create snapshot
aws ec2 create-snapshot \
  --volume-id vol-1234567890abcdef0 \
  --description "Backup before update"

Auto Scaling

# Launch Template
LaunchTemplate:
  Type: AWS::EC2::LaunchTemplate
  Properties:
    LaunchTemplateName: web-server-template
    LaunchTemplateData:
      ImageId: ami-0c55b159cbfafe1f0
      InstanceType: t3.micro
      KeyName: my-key
      SecurityGroupIds:
        - sg-12345678
      UserData:
        Fn::Base64: |
          #!/bin/bash
          yum install -y nginx
          systemctl start nginx

# Auto Scaling Group
AutoScalingGroup:
  Type: AWS::AutoScaling::AutoScalingGroup
  Properties:
    VPCZoneIdentifier:
      - subnet-12345678
      - subnet-87654321
    LaunchTemplate:
      LaunchTemplateId: !Ref LaunchTemplate
      Version: !GetAtt LaunchTemplate.LatestVersionNumber
    MinSize: 2
    MaxSize: 10
    DesiredCapacity: 2
    TargetGroupARNs:
      - !Ref TargetGroup
    HealthCheckType: ELB
    HealthCheckGracePeriod: 300

# Scaling Policies
ScalingPolicy:
  Type: AWS::AutoScaling::ScalingPolicy
  Properties:
    AutoScalingGroupName: !Ref AutoScalingGroup
    PolicyType: TargetTrackingScaling
    TargetTrackingConfiguration:
      PredefinedMetricSpecification:
        PredefinedMetricType: ASGAverageCPUUtilization
      TargetValue: 60.0

S3 (Simple Storage Service)

Object storage for the cloud.

S3 Storage Classes

ClassDurabilityAvailabilityUse Case
S3 Standard99.999999999%99.99%Frequently accessed
S3 Intelligent-Tiering99.999999999%99.9%Unknown/variable access
S3 Standard-IA99.999999999%99.9%Infrequent access
S3 One Zone-IA99.999999999%99.5%Infrequent, non-critical
S3 Glacier99.999999999%99.9%Archive, minutes retrieval
S3 Glacier Deep Archive99.999999999%99.9%Archive, hours retrieval

S3 Commands

# Create bucket
aws s3 mb s3://my-unique-bucket-name --region us-east-1

# List buckets
aws s3 ls

# Upload file
aws s3 cp file.txt s3://my-bucket/
aws s3 cp ./local-dir s3://my-bucket/remote-dir --recursive

# Download
aws s3 cp s3://my-bucket/file.txt ./local-file.txt
aws s3 sync s3://my-bucket/backup ./restore

# Presigned URL
aws s3 presign s3://my-bucket/private-file.txt --expires-in 3600

# Enable versioning
aws s3api put-bucket-versioning \
  --bucket my-bucket \
  --versioning-configuration Status=Enabled

# Set lifecycle policy
aws s3api put-bucket-lifecycle-configuration \
  --bucket my-bucket \
  --lifecycle-configuration file://lifecycle.json

S3 Security

// Bucket Policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "192.168.1.0/24"
        }
      }
    }
  ]
}
# Enable encryption
aws s3api put-bucket-encryption \
  --bucket my-bucket \
  --server-side-encryption-configuration '{
    "Rules": [{
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "AES256"
      }
    }]
  }'

# Block public access
aws s3api put-public-access-block \
  --bucket my-bucket \
  --public-access-block-configuration \
    BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

IAM (Identity and Access Management)

Manage access to AWS services and resources securely.

IAM Components

┌─────────────────────────────────────────────────────────────────┐
│                         IAM                                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   Users          Groups          Roles          Policies        │
│   ┌───┐         ┌──────┐        ┌────┐        ┌────────┐      │
│   │Alice│──────>│DevTeam│        │EC2  │        │S3Read  │      │
│   │Bob  │       │       │<───────│Role │<───────│Only    │      │
│   └───┘         └──────┘        └────┘        └────────┘      │
│     │               │              │                            │
│     └───────────────┘              └─────────────────────┐    │
│                  Attach Policies to Users/Groups/Roles      │    │
└─────────────────────────────────────────────────────────────────┘

IAM Policy Document

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EC2Access",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeInstances",
        "ec2:StartInstances",
        "ec2:StopInstances"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "ec2:Region": "us-east-1"
        },
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        }
      }
    },
    {
      "Sid": "S3ReadOnly",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::company-data",
        "arn:aws:s3:::company-data/*"
      ]
    },
    {
      "Sid": "DenyDelete",
      "Effect": "Deny",
      "Action": "s3:DeleteObject",
      "Resource": "arn:aws:s3:::company-data/protected/*"
    }
  ]
}

IAM Best Practices

# Create user
aws iam create-user --user-name developer

# Create group
aws iam create-group --group-name Developers

# Add user to group
aws iam add-user-to-group --user-name developer --group-name Developers

# Attach policy
aws iam attach-group-policy \
  --group-name Developers \
  --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess

# Create role
aws iam create-role \
  --role-name EC2S3AccessRole \
  --assume-role-policy-document file://trust-policy.json

# Attach policy to role
aws iam attach-role-policy \
  --role-name EC2S3AccessRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

VPC (Virtual Private Cloud)

Isolated network environment in AWS.

VPC Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         VPC (10.0.0.0/16)                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────────────────┐    ┌─────────────────────┐          │
│   │   Public Subnet     │    │   Private Subnet    │          │
│   │   (10.0.1.0/24)     │    │   (10.0.2.0/24)     │          │
│   │                     │    │                     │          │
│   │  ┌──────────────┐   │    │  ┌──────────────┐   │          │
│   │  │   Bastion    │   │    │  │   App Server │   │          │
│   │  │   (Jump Box) │   │    │  │   (No EIP)   │   │          │
│   │  └──────────────┘   │    │  └──────────────┘   │          │
│   │                     │    │                     │          │
│   │  ┌──────────────┐   │    │  ┌──────────────┐   │          │
│   │  │   ALB/NLB    │◄──┼────┼──│   Database   │   │          │
│   │  │   (Public)   │   │    │  │   (RDS)      │   │          │
│   │  └──────────────┘   │    │  └──────────────┘   │          │
│   │          ▲          │    │                     │          │
│   │          │          │    │                     │          │
│   │  Internet Gateway   │    │   NAT Gateway       │          │
│   └─────────────────────┘    └─────────────────────┘          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

VPC Components

# Create VPC
aws ec2 create-vpc --cidr-block 10.0.0.0/16 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=Production}]'

# Create subnets
aws ec2 create-subnet \
  --vpc-id vpc-12345678 \
  --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Public}]'

# Create Internet Gateway
aws ec2 create-internet-gateway
aws ec2 attach-internet-gateway --internet-gateway-id igw-12345678 --vpc-id vpc-12345678

# Create NAT Gateway
aws ec2 allocate-address
aws ec2 create-nat-gateway --subnet-id subnet-public --allocation-id eipalloc-12345678

# Create Route Tables
aws ec2 create-route-table --vpc-id vpc-12345678
aws ec2 create-route --route-table-id rtb-12345678 --destination-cidr-block 0.0.0.0/0 --gateway-id igw-12345678
aws ec2 associate-route-table --route-table-id rtb-12345678 --subnet-id subnet-public

Security Groups vs NACLs

FeatureSecurity GroupNACL
LevelInstanceSubnet
StatefulYesNo
RulesAllow onlyAllow + Deny
EvaluationAll rulesNumbered order
DefaultDeny all inbound, allow all outboundAllow all
# Security Group
aws ec2 create-security-group \
  --group-name web-sg \
  --description "Web server security group" \
  --vpc-id vpc-12345678

aws ec2 authorize-security-group-ingress \
  --group-id sg-12345678 \
  --protocol tcp \
  --port 443 \
  --cidr 0.0.0.0/0

Quiz

Quiz

Question 1 of 5

What is the difference between Security Groups and NACLs?

They are the same thing
Security Groups are at instance level and stateful; NACLs are at subnet level and stateless
NACLs are for EC2 only; Security Groups are for all services
Security Groups can deny traffic; NACLs cannot

Next Steps

Now let's explore AWS services specifically for DevOps: ALB, ECS, EKS, and more.