Skip to content
Merged
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
18 changes: 18 additions & 0 deletions iam_role.tf
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,21 @@ resource "aws_iam_role_policy_attachment" "s3_access" {
role = aws_iam_role.app_ec2_role.name
policy_arn = aws_iam_policy.s3_app_policy.arn
}

# -----------
# CloudWatch
# -----------

# Grants CloudWatch Agent permissions to create log groups/streams and put log events,
# and to send custom metrics (PutMetricData).
resource "aws_iam_role_policy_attachment" "cloudwatch_agent" {
role = aws_iam_role.app_ec2_role.name
policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
}

# Enables SSM connectivity (optional but highly recommended to manage the instance/agent
# without SSH and to fetch agent binaries or run commands).
resource "aws_iam_role_policy_attachment" "ssm_core" {
role = aws_iam_role.app_ec2_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
5 changes: 3 additions & 2 deletions rds.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ resource "random_password" "rds" {

# Store the generated pwd in AWS Secrets Manager
resource "aws_secretsmanager_secret" "rds" {
name = "${var.name_prefix}-rds-master-password"
description = "Master password for the ${var.name_prefix} RDS instance"
name = "${var.name_prefix}-rds-master-strong-password"
description = "Master password for the ${var.name_prefix} RDS instance"
recovery_window_in_days = 0
}

resource "aws_secretsmanager_secret_version" "rds" {
Expand Down
24 changes: 24 additions & 0 deletions route53_records.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Decide at plan time if we create DNS (e.g., public subnet envs)
variable "create_dns_record" {
type = bool
description = "Whether to create the Route53 A record for the app."
default = true
}

data "aws_route53_zone" "env" {
name = var.route53_zone_name
private_zone = false
}

# Safety check — only create the record if an IP is found
resource "aws_route53_record" "env_apex_a" {
count = var.create_dns_record != "" ? 1 : 0

zone_id = data.aws_route53_zone.env.zone_id
name = var.record_name
type = "A"
ttl = var.record_ttl
records = [aws_instance.app.public_ip]

allow_overwrite = true
}
33 changes: 33 additions & 0 deletions scripts/user_data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,36 @@ systemctl enable "${service_name}.service"
systemctl restart "${service_name}.service"

info "=== Web App started successfully ==="

# ---------------------------------------------------------------------------
# CloudWatch Agent: Refresh and start using baked config (from Packer)
# ---------------------------------------------------------------------------
CWA_BIN="/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl"
CWA_CFG="/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json"

info "=== Preparing CloudWatch Agent ==="

# Ensure application log directory exists (for ${app_dir}/log/app.log)
install -d -m 0755 -o "${app_user}" -g "${app_group}" "${app_dir}/log" || true

if [ -x "$CWA_BIN" ] && [ -f "$CWA_CFG" ]; then
info "CloudWatch Agent binary and config found. Enabling and refreshing..."

# Enable on boot (idempotent)
systemctl enable amazon-cloudwatch-agent || true

# Stop agent if running (safe if it's not)
"$CWA_BIN" -a stop || true

# Fetch baked config and start
"$CWA_BIN" -a fetch-config -m ec2 -c file:"$CWA_CFG" -s

# Check service status (non-fatal)
systemctl status amazon-cloudwatch-agent --no-pager || true

info "CloudWatch Agent started with baked config."
else
err "CloudWatch Agent binary or config not found. Skipping agent start."
fi

info "=== User data script completed successfully ==="
23 changes: 23 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,29 @@ variable "s3_prefix" {
default = ""
}

variable "route53_zone_name" {
description = "Public hosted zone name for this environment (e.g., dev.domain.tld or demo.domain.tld)"
type = string
}

variable "app_public_ip" {
description = "Fallback IP if no in-plan EC2 resource is referenced"
type = string
default = ""
}

variable "record_name" {
description = "Record name inside the zone; empty string for apex"
type = string
default = ""
}

variable "record_ttl" {
description = "TTL for A records"
type = number
default = 300
}

variable "tags" {
description = "Common tags applied to all resources"
type = map(string)
Expand Down