-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #778 from cisagov/AL-email-EC2
Create EC2 instance for sending emails
- Loading branch information
Showing
8 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#!/bin/bash | ||
|
||
# Create temporary directory for SSM Agent installation | ||
sudo mkdir -p /tmp/ssm | ||
cd /tmp/ssm || return | ||
|
||
# Download and install the SSM Agent | ||
wget https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_amd64/amazon-ssm-agent.deb | ||
sudo dpkg -i amazon-ssm-agent.deb | ||
sudo systemctl enable amazon-ssm-agent | ||
sudo systemctl start amazon-ssm-agent | ||
rm amazon-ssm-agent.deb | ||
|
||
# Update packages | ||
sudo apt-get update -y | ||
|
||
# Install Python3 and pip | ||
sudo apt-get install -y python3 python3-pip | ||
|
||
# Install necessary Python libraries | ||
pip3 install boto3 pandas | ||
|
||
# Create working directory for email script | ||
sudo mkdir -p /var/www/email_sender | ||
sudo chmod -R 755 /var/www/email_sender |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
|
||
resource "aws_iam_role" "email_sender" { | ||
count = var.create_email_sender_instance ? 1 : 0 | ||
name = "crossfeed-email-sender-${var.stage}" | ||
assume_role_policy = <<EOF | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Action": "sts:AssumeRole", | ||
"Principal": { | ||
"Service": "ec2.amazonaws.com" | ||
}, | ||
"Effect": "Allow", | ||
"Sid": "" | ||
} | ||
] | ||
} | ||
EOF | ||
|
||
tags = { | ||
Project = var.project | ||
Stage = var.stage | ||
Owner = "Crossfeed managed resource" | ||
} | ||
} | ||
|
||
resource "aws_iam_instance_profile" "email_sender" { | ||
count = var.create_email_sender_instance ? 1 : 0 | ||
name = "crossfeed-email-sender-${var.stage}" | ||
role = aws_iam_role.email_sender[0].id | ||
} | ||
|
||
# Attach Policies to the Email EC2 Role | ||
resource "aws_iam_policy_attachment" "email_sender_ec2_policy_1" { | ||
count = var.create_email_sender_instance ? 1 : 0 | ||
name = "crossfeed-email-sender-${var.stage}" | ||
roles = [aws_iam_role.email_sender[0].id, "AmazonSSMRoleForInstancesQuickSetup"] | ||
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonSSMManagedInstanceCore" | ||
} | ||
|
||
resource "aws_iam_policy_attachment" "email_sender_ec2_policy_2" { | ||
count = var.create_email_sender_instance ? 1 : 0 | ||
name = "crossfeed-email-sender-${var.stage}" | ||
roles = [aws_iam_role.email_sender[0].id] | ||
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/service-role/AmazonEC2RoleforSSM" | ||
} | ||
|
||
# EC2 Instance for SES | ||
resource "aws_instance" "email_sender" { | ||
count = var.create_email_sender_instance ? 1 : 0 | ||
ami = var.ami_id | ||
instance_type = var.email_sender_instance_type | ||
associate_public_ip_address = false | ||
|
||
depends_on = [ | ||
aws_iam_instance_profile.email_sender[0], | ||
aws_security_group.allow_internal, | ||
aws_subnet.backend | ||
] | ||
|
||
tags = { | ||
Project = var.project | ||
Stage = var.stage | ||
Name = "email_sender" | ||
Owner = "Crossfeed managed resource" | ||
} | ||
root_block_device { | ||
volume_size = 50 | ||
} | ||
|
||
vpc_security_group_ids = [var.is_dmz ? aws_security_group.allow_internal[0].id : aws_security_group.allow_internal_lz[0].id] | ||
subnet_id = var.is_dmz ? aws_subnet.backend[0].id : data.aws_ssm_parameter.subnet_db_1_id[0].value | ||
|
||
iam_instance_profile = aws_iam_instance_profile.email_sender[0].name | ||
user_data = file("./email-sender-install.sh") | ||
|
||
lifecycle { | ||
ignore_changes = [ami] | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#!/bin/bash | ||
|
||
# Configuration | ||
AWS_PROFILE=${EMAIL_AWS_PROFILE:-"default"} | ||
INSTANCE_ID=${EMAIL_SENDER_INSTANCE_ID:-"your-instance-id"} | ||
AVAILABILITY_ZONE="us-east-1b" | ||
LOCAL_PORT=9995 | ||
REMOTE_PORT=22 | ||
SSH_USER="ubuntu" | ||
SSH_KEY_PATH=${EMAIL_SSH_KEY_PATH:-""} | ||
|
||
function log_info() { | ||
echo "$(date '+%Y-%m-%d %H:%M:%S') INFO: $1" | ||
} | ||
|
||
function log_error() { | ||
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: $1" >&2 | ||
} | ||
|
||
# Check if the instance is running | ||
function get_instance_status() { | ||
aws ec2 describe-instance-status \ | ||
--instance-ids "$INSTANCE_ID" \ | ||
--profile "$AWS_PROFILE" \ | ||
--query 'InstanceStatuses[0].InstanceState.Name' \ | ||
--output text 2> /dev/null | ||
} | ||
|
||
# Start the instance if it's not running | ||
function start_instance() { | ||
log_info "Starting instance $INSTANCE_ID..." | ||
aws ec2 start-instances \ | ||
--instance-ids "$INSTANCE_ID" \ | ||
--profile "$AWS_PROFILE" \ | ||
> /dev/null | ||
|
||
log_info "Instance started. Waiting for initialization (2 minutes)..." | ||
sleep 120 | ||
} | ||
|
||
# Inject SSH Public Key using EC2 Instance Connect | ||
function send_ssh_public_key() { | ||
log_info "Sending SSH public key..." | ||
if ! aws ec2-instance-connect send-ssh-public-key \ | ||
--instance-id "$INSTANCE_ID" \ | ||
--availability-zone "$AVAILABILITY_ZONE" \ | ||
--instance-os-user "$SSH_USER" \ | ||
--ssh-public-key "file://$SSH_KEY_PATH" \ | ||
--profile "$AWS_PROFILE"; then | ||
log_error "Failed to send SSH public key." | ||
exit 1 | ||
fi | ||
} | ||
|
||
# Start port forwarding with AWS SSM | ||
function start_port_forwarding() { | ||
log_info "Starting port forwarding via SSM..." | ||
aws ssm start-session \ | ||
--target "$INSTANCE_ID" \ | ||
--document-name AWS-StartPortForwardingSession \ | ||
--parameters "{\"portNumber\":[\"$REMOTE_PORT\"], \"localPortNumber\":[\"$LOCAL_PORT\"]}" \ | ||
--profile "$AWS_PROFILE" | ||
} | ||
|
||
# Main script logic | ||
log_info "Starting EC2 connection process..." | ||
if [ -z "$INSTANCE_ID" ]; then | ||
log_error "INSTANCE_ID is not set. Please set it as an environment variable or update the script." | ||
exit 1 | ||
fi | ||
|
||
STATUS=$(get_instance_status | tr -d '\r') | ||
|
||
log_info "Current instance status: $STATUS" | ||
|
||
if [[ "$STATUS" == "running" ]]; then | ||
log_info "Instance is already running." | ||
elif [[ "$STATUS" == "stopped" || "$STATUS" == "stopping" ]]; then | ||
start_instance | ||
else | ||
log_error "Unexpected instance status: $STATUS" | ||
exit 1 | ||
fi | ||
|
||
send_ssh_public_key | ||
start_port_forwarding |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters