Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 66 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,32 @@ Please see the session recordings (coming soon) for more details.

- temporal cli installed
- terraform cli installed
- You will need a domain to which you can add DNS entries in Cloudflare and you will need to set the following env vars:
- AWS CLI installed and configured with SSO profiles
- You will need a domain to which you can add DNS entries in Cloudflare

```
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."
export CLOUDFLARE_ZONE_ID="..."
export CLOUDFLARE_API_TOKEN="..."
```
### AWS Authentication Setup

This project uses AWS SSO for authentication. Before running the application:

1. **Authenticate with AWS SSO** using one of your configured profiles:
```bash
aws sso login --profile <your AWS profile>
```

2. **Set the AWS_PROFILE environment variable** to specify which profile to use:
```bash
export AWS_PROFILE=<your AWS profile>
```

Note: If `AWS_PROFILE` is not set, Terraform will use the default AWS credential chain (which may include your default profile or other configured credentials).

3. **Set Cloudflare environment variables**:
```bash
export CLOUDFLARE_ZONE_ID="..."
export CLOUDFLARE_API_TOKEN="..."
```

**Important**: AWS SSO sessions typically expire after a few hours. If you encounter authentication errors, re-authenticate with `aws sso login --profile <your-profile>`.

You will need three command windows.

Expand Down Expand Up @@ -84,3 +102,44 @@ You will use the other two to perform the demos
1. this will end the workflow (after deprovisioning)


## Simulating a network outage

The implementation of the `get_forecast` tool includes a 10 second sleep between the two HTTP requests. Experiment with the following:
- Run it with no firewall rules
- Add the firewall rules and enable the firewall
- Disable the firewall, accept the MCP tool execution and then enable the firewall within 10 seconds. Disable the firewall on the 11th second and see what happens.


### Using `pfctl` on a Mac

We will simulate a network outage by adding firewall rules using `pfctl`. This repository includes a `pf.rules` file that will allow you to block API access to Cloudflare. The Cloudflare DNS resolution is fairly stable (some ther APIs like the National Weather Service are not) so the pf.rules file currently just has the domain name. You can check what these are right now with the following command:
```
dig +short api.cloudflare.com
```

The following commands are used to set and delete the rules, and enable and disable the firewall.

To set rules
```
sudo pfctl -f pf.rules
```

To remove the rules. WARNING: this will delete all rules - if you are using pfctl for real, use with caution.
```
sudo pfctl -F all
```

To see the current list of rules:
```
sudo pfctl -s rules
```

To enable the firewall
```
sudo pfctl -e
```

To disable the firewall
```
sudo pfctl -d
```
4 changes: 2 additions & 2 deletions cmd/starter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ func main() {
}

// Create Temporal client
c, err := client.NewClient(client.Options{
HostPort: client.DefaultHostPort,
c, err := client.Dial(client.Options{
HostPort: client.DefaultHostPort, // defaults to "localhost:7233"
})
if err != nil {
log.Fatalf("Unable to create client: %v", err)
Expand Down
2 changes: 2 additions & 0 deletions pf.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Sample firewall rules to simulate network outage
block out quick to api.cloudflare.com
5 changes: 5 additions & 0 deletions pkg/terraform/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package terraform

import (
"fmt"
"os"
"os/exec"
)

func Init(dir string) error {
cmd := exec.Command("terraform", "init")
cmd.Dir = dir
cmd.Env = os.Environ() // Explicitly inherit environment variables
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("terraform init failed: %v\n%s", err, string(output))
Expand All @@ -22,6 +24,7 @@ func Apply(dir string, autoApprove bool) error {
}
cmd := exec.Command("terraform", args...)
cmd.Dir = dir
cmd.Env = os.Environ() // Explicitly inherit environment variables
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("terraform apply failed: %v\n%s", err, string(output))
Expand All @@ -36,6 +39,7 @@ func Destroy(dir string, autoApprove bool) error {
}
cmd := exec.Command("terraform", args...)
cmd.Dir = dir
cmd.Env = os.Environ() // Explicitly inherit environment variables
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("terraform destroy failed: %v\n%s", err, string(output))
Expand All @@ -46,6 +50,7 @@ func Destroy(dir string, autoApprove bool) error {
func Untaint(dir string) error {
cmd := exec.Command("terraform", "untaint", "aws_instance.app_server")
cmd.Dir = dir
cmd.Env = os.Environ() // Explicitly inherit environment variables
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("terraform untaint failed: %v\n%s", err, string(output))
Expand Down
8 changes: 8 additions & 0 deletions pkg/workflow/activities.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ func DeployAWSInfrastructure(ctx context.Context, action string, environmentID s
logger := activity.GetLogger(ctx)
logger.Info("Starting AWS infrastructure deployment", "action", action, "environmentID", environmentID)

// Log AWS configuration for debugging
awsProfile := os.Getenv("AWS_PROFILE")
if awsProfile != "" {
logger.Info("Using AWS profile", "profile", awsProfile)
} else {
logger.Warn("AWS_PROFILE not set, using default credential chain")
}

// Get the current working directory
cwd, err := os.Getwd()
if err != nil {
Expand Down
13 changes: 10 additions & 3 deletions terraform-configs/aws-terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,22 @@ terraform {

provider "aws" {
region = "us-west-2"
# For AWS SSO, authenticate first with: aws sso login --profile <profile-name>
}

resource "aws_instance" "app_server" {
# Using a different Ubuntu 22.04 LTS AMI to force instance replacement on update
# Previous AMI: ami-0735c191cf914754d
# Previous AMI: ami-08d70e59c07c61a3a
ami = "ami-08d70e59c07c61a3a"
# Previous AMI: ami-0ffde298a37fd43b7
# Current AMI: ami-053ee446a8202ddd8

ami = "ami-0ffde298a37fd43b7"
instance_type = "t2.micro"

metadata_options {
http_tokens = "required" # Required by SCP to use IMDSv2
http_endpoint = "enabled"
}

tags = {
Name = "ExampleAppServerInstance"
}
Expand Down