---
title: "AWS Operations Guide"
author: "Claude and JonC"
description: "A step-by-step reference for working with core AWS services: EC2, S3  IAM, Security Groups, and CloudWatch."
published: "2026-02-24"
---

## Getting Into AWS

### Logging In (AWS Academy)

1. Go to `https://awsacademy.instructure.com/login/canvas`
2. Log in with your student email (`lastnamef@students.westerntc.edu`)
3. From the Dashboard, select **AWS Academy Learner Lab**
4. In the left menu, select **Modules**
5. Click **Launch AWS Academy Learner Lab**
6. Click **Start Lab** at the top — wait for the circle next to "AWS" to turn green
7. Click **AWS** on the left to open the AWS Management Console
8. When done, click **End Lab** to stop the environment and avoid unnecessary charges

*Note: Every time you return, you must restart the lab from step 6. The environment does not persist between sessions.*

---

## Getting Your AWS Credentials (for CLI/GitHub Actions)

1. Start the lab as above
2. Click **AWS Details** (next to "End Lab")
3. Click **Show** next to **AWS CLI**
4. Note the three values — you will need these for GitHub Secrets or any CLI configuration:
   - `AWS_ACCESS_KEY_ID`
   - `AWS_SECRET_ACCESS_KEY`
   - `AWS_SESSION_TOKEN`

*These credentials expire when the lab session ends. You must retrieve new ones each session.*

---

## EC2 — Elastic Compute Cloud

EC2 provides virtual servers (called instances) in the cloud. You use them to run operating systems, host web applications, and run services.

### Launching an EC2 Instance

1. In the AWS Console, go to **Services → Compute → EC2**
2. Click the orange **Launch Instance** button
3. Configure the following settings:

| Setting | Value |
|---|---|
| Name | `DevOps Server` (or your chosen name) |
| Amazon Machine Image (AMI) | Red Hat Enterprise Linux 9 — Free tier eligible |
| Architecture | 64-bit (x86) |
| Instance Type | `t3.medium` (2 vCPUs, 4GB RAM) — use `t2.micro` for free tier |
| Key Pair | Create a new key pair (see below) |
| Network Settings | Create a security group; check "Allow SSH traffic from Anywhere" |
| Storage | 1x 10 GiB gp3 Root volume |
| Number of Instances | 1 |

4. Click **Launch Instance**

*An instance at t2.micro qualifies for the AWS free tier. t3.medium is required for running a database (MySQL) alongside other services.*

### Creating a Key Pair

*This key pair is what allows you to SSH into your instance. Treat it like a password — if you lose it, you cannot access the instance.*

1. In the key pair step during launch, click **Create new key pair**
2. Name it (e.g., `Western-Student`)
3. Key pair type: **RSA**
4. Private key format: `.ppk` for PuTTY on Windows; `.pem` for Mac/Linux terminal
5. Click **Create key pair** — the file downloads automatically
6. Save the file somewhere safe and back it up

### Finding Your Instance's Public Address

1. Go to **EC2 → Instances**
2. Click on your instance ID
3. Copy the **Public IPv4 DNS** — it looks like `ec2-XX-XX-XX-XX.compute-1.amazonaws.com`

*This address changes every time the instance is stopped and restarted.*

### Connecting to Your Instance via Browser Console

1. In EC2, select your instance
2. Click **Connect** at the top
3. On the Connect page, click **Connect** at the bottom
4. A Linux terminal opens in your browser

### Starting, Stopping, and Changing Instance Type

1. Select your instance in the EC2 dashboard
2. Click **Instance state** at the top
3. To stop: select **Stop instance → Stop**
4. Once stopped, click **Actions → Instance settings → Change instance type**
5. Type the new instance type (e.g., `t3.medium`) and click **Change**
6. Click **Instance state → Start instance**

### Installing and Running a Web Server (Apache) on EC2

```bash
sudo yum install httpd          # Install Apache (use yum on Amazon Linux)
sudo systemctl start httpd      # Start the service
```

*Navigate to the instance's public IP in a browser using HTTP (not HTTPS) to see the Apache default page. Make sure port 80 is open in the security group.*

### Installing Updates on Your Instance

```bash
sudo dnf -y update
```

*Run this immediately after connecting to a new instance to apply all security and software updates.*

---

## Security Groups

Security groups act as virtual firewalls, controlling what traffic can reach your EC2 instances. Rules are additive — there is no explicit deny; anything not listed is blocked by default.

### Opening the Security Group Editor

1. Go to **EC2 Dashboard**
2. In the Resources section at the top, click **Security groups**
3. Click the security group ID associated with your instance (usually `launch-wizard-1`)

### Adding Inbound Rules

1. Under **Inbound rules**, click **Edit inbound rules**
2. Click **Add rule**
3. Select the **Type** (e.g., SSH, HTTP, All traffic, All ICMP – IPv4)
4. Select the **Source** (e.g., Anywhere-IPv4, My IP, Custom)
5. Click **Save rules**

**Common rule configurations:**

| Purpose | Type | Port | Source |
|---|---|---|---|
| SSH access | SSH | 22 | Anywhere-IPv4 (or My IP for more security) |
| Web server | HTTP | 80 | Anywhere-IPv4 |
| Docker documentation service | Custom TCP | 8081 | Anywhere-IPv4 |
| Docker Joomla/CMS | Custom TCP | 8090 | Anywhere-IPv4 |
| Allow all (lab/dev only) | All traffic | All | Anywhere-IPv4 |
| Ping (ICMP) | All ICMP – IPv4 | N/A | Anywhere-IPv4 |

*Opening "All traffic from Anywhere" is acceptable in a lab environment but should never be used in production. Tighten rules to only the ports you actually serve.*

### Restricting Access by IP

1. Edit inbound rules for SSH
2. Change Source from **Anywhere-IPv4** to **My IP**
3. AWS auto-fills your current public IP

*This limits SSH access to only your current IP address. If your IP changes (e.g., switching networks), you will need to update this rule.*

---

## S3 — Simple Storage Service

S3 stores files (called objects) in containers called buckets. It is commonly used for backups, static website hosting, and serving images or assets to web applications.

### Creating an S3 Bucket

1. Go to **Services → Storage → S3** (or search "S3")
2. Click **Create bucket**
3. Enter a globally unique bucket name (e.g., `my-cicd-bucket-yourusername`)
4. Under **Block Public Access Settings**, uncheck **Block all public access** if you need public access
5. Check the acknowledgment box that appears
6. Scroll down and click **Create bucket**

*Bucket names must be globally unique across all of AWS. Include your username to ensure uniqueness.*

### Setting a Bucket Policy for Public Read Access

1. Click on your bucket name
2. Select the **Permissions** tab
3. Scroll to **Bucket policy** and click **Edit**
4. Paste the following, replacing `YOUR_BUCKET_NAME`:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
    }
  ]
}
```

5. Click **Save changes**

*This allows anyone on the internet to read files from your bucket. Required for static website hosting and serving images to your documentation.*

### Uploading Files

1. Click on your bucket name
2. Select the **Objects** tab
3. Click **Upload → Add files**
4. Select the files from your local machine
5. Scroll down and click **Upload**
6. Click **Close**

### Getting a File's Public URL

1. Click on the uploaded file under **Objects**
2. Click **Copy URL**
3. Test in a private/incognito browser window to confirm public access

*The URL format is: `https://bucket-name.s3.region.amazonaws.com/filename`*

### Referencing an S3 Image in Markdown

```markdown
![Alt text description](https://your-bucket-name.s3.us-east-1.amazonaws.com/image.png)
```

### Enabling Static Website Hosting

1. Click your bucket name → **Properties** tab
2. Scroll to **Static website hosting** → click **Edit**
3. Select **Enable**
4. Set **Index document** to `index.html`
5. Click **Save changes**
6. Scroll back down to copy the **Bucket website endpoint** URL

*The website endpoint URL (http) is different from the object URL (https). Use the website endpoint when linking to the site as a whole.*

### Enabling Bucket Versioning

1. Click your bucket name → **Properties** tab
2. Click **Edit** next to **Bucket Versioning**
3. Select **Enable**
4. Click **Save changes**

*Versioning saves every uploaded version of a file. You can restore previous versions from the object's Versions tab.*

### Configuring a Lifecycle Rule (Automatic Archiving)

1. Click your bucket name → **Management** tab
2. Click **Create lifecycle rule**
3. Name the rule and select the scope
4. Add a transition action: move to **Glacier** after 30 days
5. Optionally add an expiration action: delete after 90 days
6. Click **Save**

---

## IAM — Identity and Access Management

IAM controls who can access what in your AWS account. You create users, groups, roles, and attach policies to define permissions.

### Creating an IAM User

1. Go to **Services → Security → IAM** (or search "IAM")
2. Click **Users → Add User**
3. Set a username
4. Select **Console access**
5. Set a custom password; uncheck "Users must create a new password at next sign-in"
6. Click **Next**
7. Under **Set permissions**, select **Attach policies directly**
8. Search for and select a policy (e.g., `AmazonS3FullAccess`)
9. Click **Next → Create user**

*In the AWS Academy Learner Lab, user creation is blocked by the lab environment. The steps above reflect real-world usage.*

### Common Predefined Policies

| Policy | Access Granted |
|---|---|
| `AmazonS3FullAccess` | Full read/write access to all S3 buckets |
| `AmazonEC2FullAccess` | Full control over all EC2 instances and resources |
| `AdministratorAccess` | Full access to all AWS services — use sparingly |
| `ReadOnlyAccess` | Read-only access to all services |

---

## CloudWatch — Monitoring and Alarms

CloudWatch collects performance metrics from your AWS resources and can trigger alarms when thresholds are exceeded.

### Setting a CPU Utilization Alarm

1. Search for **CloudWatch** in the AWS console
2. In the left menu, click **Alarms → All alarms**
3. Click **Create alarm**
4. Click **Select metric → EC2 → Per-Instance Metrics**
5. Find your instance ID and select **CPUUtilization**
6. Click **Select metric**
7. Set the threshold: **Greater than 70%** over 1 evaluation period
8. Configure notifications if desired
9. Name the alarm and click **Create alarm**

### Generating CPU Load to Test an Alarm

```bash
sudo amazon-linux-extras enable epel   # Enable extra package repositories
sudo yum install -y epel-release       # Install the EPEL repository
sudo yum install -y stress             # Install the stress testing tool
sudo stress --cpu 1 --timeout 120      # Run a 1-core CPU stress test for 120 seconds
```

*After running this, navigate to CloudWatch and watch the alarm state change from OK to ALARM.*

---

## Billing Alerts (Real-World — Not Available in Learner Lab)

1. Go to **Services → Cloud Financial Management → Billing and Cost Management**
2. On the left menu, click **Budgets**
3. Click **Create budget**
4. Accept the defaults: **Use a template → Zero spend budget**
5. Enter your email under **Email recipients**
6. Click **Create budget**

*This sends an email notification immediately when any billable charge occurs. Essential for avoiding unexpected costs.*

---

## GitHub Actions Secrets for AWS Deployment

After retrieving your credentials from AWS Details, add them to your GitHub repository:

1. In your GitHub repo, go to **Settings → Secrets and variables → Actions**
2. Click **New repository secret** for each of the following:

| Secret Name | Value |
|---|---|
| `AWS_ACCESS_KEY_ID` | From AWS Details → AWS CLI |
| `AWS_SECRET_ACCESS_KEY` | From AWS Details → AWS CLI |
| `AWS_SESSION_TOKEN` | From AWS Details → AWS CLI |
| `AWS_REGION` | `us-east-1` |
| `S3_BUCKET_NAME` | Your bucket name (e.g., `my-cicd-bucket-yourusername`) |
| `EC2_SSH_KEY` | Full contents of your `.pem` private key file |
| `EC2_HOST` | Your EC2 instance's Public IPv4 DNS |

*Secrets are encrypted and never visible after being saved. If you need to update a value, you must overwrite it by creating a new secret with the same name.*
