├── README.md ├── nginx-ha-check ├── LICENSE └── nginx-ha-notify /README.md: -------------------------------------------------------------------------------- 1 | # Active-Passive HA Deployment on AWS Using an Elastic IP Address 2 | 3 | With this keepalived-based solution, you can create an active-passive HA deployment of NGINX Plus on AWS using an Elastic IP address. This repo contains the files necessary to create such a deployment. To learn more about this solution and see the deployment instructions, visit [NGINX Admin Guide](https://docs.nginx.com/nginx/deployment-guides/amazon-web-services/high-availability-keepalived/). 4 | -------------------------------------------------------------------------------- /nginx-ha-check: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PATH=/bin:/sbin:/usr/bin:/usr/sbin 4 | 5 | STATEFILE=/var/run/nginx-ha-keepalived.state 6 | 7 | if [ -s "$STATEFILE" ]; then 8 | . "$STATEFILE" 9 | case "$STATE" in 10 | "BACKUP"|"MASTER"|"FAULT") 11 | service nginx status 12 | exit $? 13 | ;; 14 | *|"") 15 | logger -t nginx-ha-keepalived "Unknown state: '$STATE'" 16 | exit 1 17 | ;; 18 | esac 19 | fi 20 | 21 | service nginx status 22 | exit $? 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Nginx, Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 | * SUCH DAMAGE. 25 | */ 26 | -------------------------------------------------------------------------------- /nginx-ha-notify: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #############--USER DEFINED VARIABLES SET HERE--############## 4 | #Set the AWS credentials here if you didn't create an IAM instance profile 5 | #export AWS_ACCESS_KEY_ID= 6 | #export AWS_SECRET_ACCESS_KEY= 7 | 8 | #Set the AWS default region 9 | export AWS_DEFAULT_REGION= 10 | 11 | #Set the internal or private DNS names of the HA nodes here 12 | HA_NODE_1= 13 | HA_NODE_2= 14 | 15 | #Set the ElasticIP ID Value here 16 | ALLOCATION_ID= 17 | ############################################################### 18 | 19 | PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 20 | 21 | #Values passed in from keepalived 22 | TYPE=$1 23 | NAME=$2 24 | STATE=$3 25 | 26 | #Determine the internal or private dns name of the instance 27 | LOCAL_INTERNAL_DNS_NAME=`wget -q -O - http://169.254.169.254/latest/meta-data/local-hostname` 28 | LOCAL_INTERNAL_DNS_NAME=`echo $LOCAL_INTERNAL_DNS_NAME | sed -e 's/% //g'` 29 | 30 | #OTHER_INSTANCE_DNS_NAME is the other node than this one, default assignment is HA_NODE_1 31 | OTHER_INSTANCE_DNS_NAME=$HA_NODE_1 32 | 33 | #Use LOCAL_INTERNAL_DNS_NAME to determine which node this is and to set the Other Node name 34 | if [ "$HA_NODE_1" = "$LOCAL_INTERNAL_DNS_NAME" ] 35 | then 36 | OTHER_INSTANCE_DNS_NAME=$HA_NODE_2 37 | fi 38 | 39 | #Get the local instance ID 40 | INSTANCE_ID=`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id` 41 | INSTANCE_ID=`echo $INSTANCE_ID | sed -e 's/% //g'` 42 | 43 | #Get the instance ID of the other node 44 | OTHER_INSTANCE_ID=`aws ec2 describe-instances --filter "Name=private-dns-name,Values=$OTHER_INSTANCE_DNS_NAME" | /usr/bin/python -c 'import json,sys;obj=json.load(sys.stdin); print obj["Reservations"][0]["Instances"][0]["InstanceId"]'` 45 | 46 | #Get the ASSOCIATION_ID of the ElasticIP to the Instance 47 | ASSOCIATION_ID=`aws ec2 describe-addresses --allocation-id $ALLOCATION_ID | /usr/bin/python -c 'import json,sys;obj=json.load(sys.stdin); print obj["Addresses"][0]["AssociationId"]'` 48 | 49 | #Get the INSTANCE_ID of the system the ElasticIP is associated with 50 | EIP_INSTANCE=`aws ec2 describe-addresses --allocation-id $ALLOCATION_ID | /usr/bin/python -c 'import json,sys;obj=json.load(sys.stdin); print obj["Addresses"][0]["InstanceId"]'` 51 | 52 | STATEFILE=/var/run/nginx-ha-keepalived.state 53 | 54 | logger -t nginx-ha-keepalived "Params and Values: TYPE=$TYPE -- NAME=$NAME -- STATE=$STATE -- ALLOCATION_ID=$ALLOCATION_ID -- INSTANCE_ID=$INSTANCE_ID -- OTHER_INSTANCE_ID=$OTHER_INSTANCE_ID -- EIP_INSTANCE=$EIP_INSTANCE -- ASSOCIATION_ID=$ASSOCIATION_ID -- STATEFILE=$STATEFILE" 55 | 56 | logger -t nginx-ha-keepalived "Transition to state '$STATE' on VRRP instance '$NAME'." 57 | 58 | case $STATE in 59 | "MASTER") 60 | aws ec2 disassociate-address --association-id $ASSOCIATION_ID 61 | aws ec2 associate-address --allocation-id $ALLOCATION_ID --instance-id $INSTANCE_ID 62 | service nginx start ||: 63 | echo "STATE=$STATE" > $STATEFILE 64 | exit 0 65 | ;; 66 | "BACKUP"|"FAULT") 67 | if [ "$INSTANCE_ID" = "$EIP_INSTANCE" ] 68 | then 69 | aws ec2 disassociate-address --association-id $ASSOCIATION_ID 70 | aws ec2 associate-address --allocation-id $ALLOCATION_ID --instance-id $OTHER_INSTANCE_ID 71 | logger -t nginx-ha-keepalived "BACKUP Path Transfer from $INSTANCE_ID to $OTHER_INSTANCE_ID" 72 | fi 73 | echo "STATE=$STATE" > $STATEFILE 74 | exit 0 75 | ;; 76 | *) logger -t nginx-ha-keepalived "Unknown state: '$STATE'" 77 | exit 1 78 | ;; 79 | esac 80 | --------------------------------------------------------------------------------