add support for running feature server in aws autoscale group with sns lifecycle notifications

This commit is contained in:
Dave Horton
2020-04-19 16:42:03 -04:00
parent a5c6fe0fdf
commit 686303077f
7 changed files with 249 additions and 6 deletions

View File

@@ -1,6 +1,6 @@
# jambonz infrastructure
This repository contains [packer](packer.io) and [terraform](terraform.io) scripts for deploying ja,mbonz on AWS. Packer scripts build the necessary AMIs, and terraform scripts create the full AWS infrastructure using those AMIs.
This repository contains [packer](packer.io) and [terraform](terraform.io) scripts for deploying jambonz on AWS hosted infrastructure. Packer scripts build the necessary AMIs, and terraform scripts create the full AWS infrastructure using those AMIs.
There are 3 different deployment alternatives:

View File

@@ -20,6 +20,7 @@ module.exports = {
AWS_ACCESS_KEY_ID: '${AWS_ACCESS_KEY_ID}',
AWS_SECRET_ACCESS_KEY: '${AWS_SECRET_ACCESS_KEY}',
AWS_REGION: '${AWS_REGION}',
AWS_SNS_TOPIC_ARM: '${AWS_SNS_TOPIC_ARN}',
ENABLE_DATADOG_METRICS: 0,
ENABLE_DATADOG_METRICS: 0,
JAMBONES_NETWORK_CIDR: '${VPC_CIDR}',
@@ -38,7 +39,7 @@ module.exports = {
JAMBONES_SBCS: '${JAMBONES_SBC_SIP_IPS}',
JAMBONES_FEATURE_SERVERS: '127.0.0.1:9022:cymru',
JAMBONES_FREESWITCH: '127.0.0.1:8021:JambonzR0ck$'
}
}
}]
};
EOF

View File

@@ -0,0 +1,131 @@
# create an SNS notification topic
resource "aws_sns_topic" "jambonz-sns-topic" {
name = var.sns_topic
}
# create an IAM role that allows publishing to the SNS topic
#data "aws_iam_policy_document" "jambonz_sns_publish" {
# statement {
# actions = [
# "sns:Publish"
# ]
# resources = [
# aws_sns_topic.jambonz-sns-topic.arn
# ]
# }
#}
resource "aws_iam_role" "jambonz_sns_publish" {
name = "jambonz_sns_publish"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"autoscaling.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_policy" "allow_jambonz_sns_publish" {
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sns:Publish"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "sns-publish-policy-attachment" {
role = aws_iam_role.jambonz_sns_publish.name
policy_arn = aws_iam_policy.allow_jambonz_sns_publish.arn
}
# select the most recent jambonz AMIs
data "aws_ami" "jambonz-feature-server" {
most_recent = true
name_regex = "^jambonz-feature-server"
owners = ["376029039784"]
}
# create a launch configuration
resource "aws_launch_configuration" "jambonz-feature-server" {
image_id = data.aws_ami.jambonz-feature-server.id
instance_type = var.ec2_instance_type
associate_public_ip_address = true
security_groups = [aws_security_group.allow_jambonz_feature_server.id]
key_name = var.key_name
user_data = templatefile("${path.module}/feature-server.ecosystem.config.js.tmpl", {
VPC_CIDR = var.vpc_cidr_block
JAMBONES_SBC_SIP_IPS = join(",", var.jambonz_sbc_sip_private_ips)
JAMBONES_MYSQL_HOST = aws_rds_cluster.jambonz.endpoint
JAMBONES_MYSQL_USER = aws_rds_cluster.jambonz.master_username
JAMBONES_MYSQL_PASSWORD = aws_rds_cluster.jambonz.master_password
JAMBONES_REDIS_HOST = aws_elasticache_cluster.jambonz.cache_nodes.0.address
AWS_ACCESS_KEY_ID = var.aws_access_key_id_runtime
AWS_SECRET_ACCESS_KEY = var.aws_secret_access_key_runtime
AWS_REGION = var.region
AWS_SNS_TOPIC_ARN = aws_sns_topic.jambonz-sns-topic.arn
})
lifecycle {
create_before_destroy = true
}
}
# create a placement group to spread feature server instances
resource "aws_placement_group" "jambonz-feature-server" {
name = "jambonz-feature-server"
strategy = "spread"
}
# create an autoscaling group
resource "aws_autoscaling_group" "jambonz-feature-server" {
min_size = 1
max_size = 2
desired_capacity = 1
force_delete = true
placement_group = aws_placement_group.jambonz-feature-server.id
launch_configuration = aws_launch_configuration.jambonz-feature-server.name
termination_policies = ["OldestInstance"]
vpc_zone_identifier = local.my_subnet_ids
tag {
key = "Name"
value = "jambonz-feature-server"
propagate_at_launch = true
}
lifecycle {
create_before_destroy = true
}
}
# create lifecycle hooks
resource "aws_autoscaling_lifecycle_hook" "jambonz-scale-in" {
name = "jambonz-scale-in"
autoscaling_group_name = aws_autoscaling_group.jambonz-feature-server.name
default_result = "CONTINUE"
heartbeat_timeout = 900
lifecycle_transition = "autoscaling:EC2_INSTANCE_TERMINATING"
notification_target_arn = aws_sns_topic.jambonz-sns-topic.arn
role_arn = aws_iam_role.jambonz_sns_publish.arn
}

View File

@@ -213,13 +213,21 @@ resource "aws_security_group" "allow_jambonz_feature_server" {
}
ingress {
description = "http"
description = "http from sbc/api servers"
from_port = 3000
to_port = 3000
protocol = "tcp"
cidr_blocks = [aws_vpc.jambonz.cidr_block]
}
ingress {
description = "http from aws sns"
from_port = 3001
to_port = 3001
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "sip from VPC"
from_port = 5060

View File

@@ -106,6 +106,7 @@ module.exports = {
JAMBONES_MYSQL_CONNECTION_LIMIT: 10,
JAMBONES_REDIS_HOST: '${JAMBONES_REDIS_HOST}',
JAMBONES_REDIS_PORT: 6379,
MS_TEAMS_FQDN: '${MS_TEAMS_FQDN}'
}
},
{
@@ -136,6 +137,7 @@ module.exports = {
JAMBONES_MYSQL_CONNECTION_LIMIT: 10,
JAMBONES_REDIS_HOST: '${JAMBONES_REDIS_HOST}',
JAMBONES_REDIS_PORT: 6379,
MS_TEAMS_SIP_PROXY_IPS: '52.114.148.0, 52.114.132.46, 52.114.75.24, 52.114.76.76, 52.114.7.24, 52.114.14.70'
}
}]
};

View File

@@ -0,0 +1,93 @@
# Create SBC SIP instances
data "aws_ami" "jambonz-sbc-sip" {
most_recent = true
name_regex = "^jambonz-sbc-sip"
owners = ["376029039784"]
}
resource "aws_eip" "jambonz-sbc-sip" {
count = length(var.jambonz_sbc_sip_private_ips)
instance = aws_instance.jambonz-sbc-sip-server[count.index].id
vpc = true
}
resource "aws_instance" "jambonz-sbc-sip-server" {
count = length(var.jambonz_sbc_sip_private_ips)
ami = data.aws_ami.jambonz-sbc-sip.id
instance_type = var.ec2_instance_type
private_ip = var.jambonz_sbc_sip_private_ips[count.index]
subnet_id = local.my_subnet_ids[count.index]
vpc_security_group_ids = [aws_security_group.allow_jambonz_sbc_sip.id]
user_data = templatefile("${path.module}/sbc-sip-server.ecosystem.config.js.tmpl", {
VPC_CIDR = var.vpc_cidr_block
JAMBONES_FEATURE_SERVER_FOR_API_CALLS = var.jambonz_feature_server_private_ips[0]
JAMBONES_FEATURE_SERVER_IPS = join(",", var.jambonz_feature_server_private_ips)
JAMBONES_SBC_SIP_IPS = join(",", var.jambonz_sbc_sip_private_ips)
JAMBONES_RTPENGINE_IPS = join(",", local.rtpengine_hostports)
JAMBONES_MYSQL_HOST = aws_rds_cluster.jambonz.endpoint
JAMBONES_MYSQL_USER = aws_rds_cluster.jambonz.master_username
JAMBONES_MYSQL_PASSWORD = aws_rds_cluster.jambonz.master_password
JAMBONES_REDIS_HOST = aws_elasticache_cluster.jambonz.cache_nodes.0.address
MS_TEAMS_FQDN = var.ms_teams_fqdn
})
key_name = var.key_name
monitoring = true
depends_on = [aws_internet_gateway.jambonz, aws_elasticache_cluster.jambonz, aws_rds_cluster.jambonz]
tags = {
Name = "jambonz-sbc-sip-server"
}
}
# Create SBC RTP instances
data "aws_ami" "jambonz-sbc-rtp" {
most_recent = true
name_regex = "^jambonz-sbc-rtp"
owners = ["376029039784"]
}
resource "aws_eip" "jambonz-sbc-rtp" {
count = length(var.jambonz_sbc_rtp_private_ips)
instance = aws_instance.jambonz-sbc-rtp-server[count.index].id
vpc = true
}
resource "aws_instance" "jambonz-sbc-rtp-server" {
count = length(var.jambonz_sbc_rtp_private_ips)
ami = data.aws_ami.jambonz-sbc-rtp.id
instance_type = var.ec2_instance_type
private_ip = var.jambonz_sbc_rtp_private_ips[count.index]
subnet_id = local.my_subnet_ids[count.index]
vpc_security_group_ids = [aws_security_group.allow_jambonz_sbc_rtp.id]
key_name = var.key_name
monitoring = true
depends_on = [aws_internet_gateway.jambonz]
tags = {
Name = "jambonz-sbc-rtp-server"
}
}
# seed the database, from one of the feature servers
resource "null_resource" "seed" {
# Bootstrap script can run on any instance of the cluster
# So we just choose the first in this case
connection {
type = "ssh"
user = "admin"
host = element(aws_eip.jambonz-sbc-sip.*.public_ip, 0)
}
provisioner "remote-exec" {
inline = [
"mysql -h ${aws_rds_cluster.jambonz.endpoint} -u admin -D jambones -pJambonzR0ck$ < /home/admin/apps/jambonz-api-server/db/jambones-sql.sql",
"mysql -h ${aws_rds_cluster.jambonz.endpoint} -u admin -D jambones -pJambonzR0ck$ < /home/admin/apps/jambonz-api-server/db/create-admin-token.sql",
]
}
depends_on = [aws_rds_cluster.jambonz, aws_instance.jambonz-sbc-sip-server]
}

View File

@@ -1,6 +1,6 @@
variable "region" {
description = "the aws region in which to create the VPC"
default = "us-east-1"
default = "us-west-2"
}
variable "vpc_cidr_block" {
description = "the CIDR block for the whole VPC"
@@ -9,8 +9,8 @@ variable "vpc_cidr_block" {
variable "public_subnets" {
type = map(string)
default = {
"us-east-1a" = "172.31.32.0/24"
"us-east-1b" = "172.31.33.0/24"
"us-west-2a" = "172.31.32.0/24"
"us-west-2b" = "172.31.33.0/24"
}
}
variable "jambonz_sbc_sip_private_ips" {
@@ -41,3 +41,11 @@ variable "aws_secret_access_key_runtime" {
description = "AWS secret access key jambonz will use to access AWS Polly TTS"
default = "your-aws-secret_access-key"
}
variable "sns_topic" {
description = "AWS SNS topic for autoscale events"
default = "jambonz-fs-lifecycle-events"
}
variable "ms_teams_fqdn" {
description = "Microsoft Teams FQDN"
default = ""
}