diff --git a/README.md b/README.md
index c431a35dc1d..109750dd0bb 100644
--- a/README.md
+++ b/README.md
@@ -45,6 +45,11 @@ and often rely on network ACLs and manual updating.
* [ZMS Server](docs/setup_zms_prod.md)
* [ZTS Server](docs/setup_zts_prod.md)
* [UI Server](docs/setup_ui_prod.md)
+* AWS Setup
+ * [Introduction](docs/aws_athenz_setup.md)
+ * [ZMS Server](docs/aws_zms_setup.md)
+ * [ZTS Server](docs/aws_zts_setup.md)
+ * [UI Server](docs/aws_ui_setup.md)
* Architecture
* [Data Model](docs/data_model.md)
* [System View](docs/system_view.md)
diff --git a/assembly/ui/pom.xml b/assembly/ui/pom.xml
index d38bd0796fc..9fa4a05fcb7 100644
--- a/assembly/ui/pom.xml
+++ b/assembly/ui/pom.xml
@@ -58,6 +58,21 @@
+
+ package-ui-assembly-aws
+ package
+
+ single
+
+
+ posix
+ ../../../athenz/aws-setup/ui-setup/tars/
+ athenz-ui
+
+ ui.xml
+
+
+
diff --git a/assembly/zms/pom.xml b/assembly/zms/pom.xml
index f0430af1e2a..9b56219a727 100644
--- a/assembly/zms/pom.xml
+++ b/assembly/zms/pom.xml
@@ -72,6 +72,21 @@
+
+ package-zms-assembly-aws
+ package
+
+ single
+
+
+ posix
+ ../../../athenz/aws-setup/zms-setup/tars/
+ athenz-zms
+
+ zms.xml
+
+
+
diff --git a/assembly/zts/pom.xml b/assembly/zts/pom.xml
index b679c4ee00f..16e4de6b105 100644
--- a/assembly/zts/pom.xml
+++ b/assembly/zts/pom.xml
@@ -72,6 +72,21 @@
+
+ package-zts-assembly-aws
+ package
+
+ single
+
+
+ posix
+ ../../../athenz/aws-setup/zts-setup/tars/
+ athenz-zts
+
+ zts.xml
+
+
+
diff --git a/aws-setup/athenz-conf-aws/Makefile b/aws-setup/athenz-conf-aws/Makefile
new file mode 100755
index 00000000000..86a19d722ed
--- /dev/null
+++ b/aws-setup/athenz-conf-aws/Makefile
@@ -0,0 +1,77 @@
+#
+# Makefile to build Athenz Config file generation utility
+# Prerequisite: Go development environment
+#
+# Copyright 2018 Oath, Inc.
+# Licensed under the Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0
+#
+
+GOPKGNAME = github.com/yahoo/athenz/utils/athenz-conf-aws
+PKG_DATE=$(shell date '+%Y-%m-%dT%H:%M:%S')
+BINARY=athenz-conf-aws
+SRC=athenz-conf-aws.go
+FMT_LOG=/tmp/athenz-conf-aws-fmt.log
+IMPORTS_LOG=/tmp/athenz-conf-aws-imports.log
+
+# check to see if go utility is installed
+GO := $(shell command -v go 2> /dev/null)
+export GOPATH=$(PWD)
+
+ifdef GO
+
+# we need to make sure we have go 1.7+
+# the output for the go version command is:
+# go version go1.7.3 darwin/amd64
+
+GO_VER_GTEQ7 := $(shell expr `go version | cut -f 3 -d' ' | cut -f2 -d.` \>= 7)
+ifneq "$(GO_VER_GTEQ7)" "1"
+all:
+ @echo "Please install 1.7.x or newer version of golang"
+else
+
+.PHONY: source vet fmt imports linux darwin
+all: source vet fmt imports linux darwin
+
+endif
+
+else
+
+all:
+ @echo "go is not available please install golang"
+
+endif
+
+# we need to build the athenz-conf with the local copy
+
+source:
+ @echo "Cleanup up local GOPATH src directory..."
+ rm -rf src
+ @echo "Setting up the source code..."
+ mkdir -p /tmp/athenz-conf-aws-build/src/$(GOPKGNAME)
+ cp -r * /tmp/athenz-conf-aws-build/src/$(GOPKGNAME)/.
+ mv /tmp/athenz-conf-aws-build/src .
+ @echo "Getting dependency packages..."
+ go get -t -d -tags testing $(GOPKGNAME)/...
+
+imports:
+ go get golang.org/x/tools/cmd/goimports
+ go list $(GOPKGNAME)/... | sed "s:^:$(GOPATH)/src/:" | xargs $(GOPATH)/bin/goimports -d >$(IMPORTS_LOG)
+ @if [ -s $(IMPORTS_LOG) ]; then echo goimports FAIL; cat $(IMPORTS_LOG); false; fi
+
+vet:
+ go vet $(GOPKGNAME)/...
+
+fmt:
+ go list $(GOPKGNAME)/... | sed "s:^:$(GOPATH)/src/:" | xargs gofmt -d >$(FMT_LOG)
+ @if [ -s $(FMT_LOG) ]; then echo gofmt FAIL; cat $(FMT_LOG); false; fi
+
+darwin:
+ @echo "Building darwin client..."
+ GOOS=darwin go build -ldflags "-X main.VERSION=$(PKG_VERSION) -X main.BUILD_DATE=$(PKG_DATE)" -o target/darwin/$(BINARY) $(SRC)
+
+linux:
+ @echo "Building linux client..."
+ GOOS=linux go build -ldflags "-X main.VERSION=$(PKG_VERSION) -X main.BUILD_DATE=$(PKG_DATE)" -o target/linux/$(BINARY) $(SRC)
+
+clean:
+ rm -rf target src bin pkg /tmp/athenz-conf-aws-build $(FMT_LOG) $(IMPORTS_LOG)
diff --git a/aws-setup/athenz-conf-aws/athenz-conf-aws.go b/aws-setup/athenz-conf-aws/athenz-conf-aws.go
new file mode 100755
index 00000000000..c644e5341d7
--- /dev/null
+++ b/aws-setup/athenz-conf-aws/athenz-conf-aws.go
@@ -0,0 +1,94 @@
+package main
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "log"
+ "io/ioutil"
+ "os"
+
+ "github.com/yahoo/athenz/libs/go/zmssvctoken"
+)
+
+func usage() string {
+ var buf bytes.Buffer
+ buf.WriteString("usage: athenz-conf-aws -z -k [flags]\n")
+ buf.WriteString(" flags:\n")
+ buf.WriteString(" -z zms_url Base URL of the ZMS server to use\n")
+ buf.WriteString(" -k zms_public key Public key of ZMS server to use\n" )
+ buf.WriteString(" -t zts_url Base URL of the ZTS server to use\n")
+ buf.WriteString(" -e zts_public key Public key of zms server to use\n" )
+ buf.WriteString(" -o output_file Output config filename (default=/opt/zts/conf/athenz.conf)\n" )
+ buf.WriteString("\n")
+ return buf.String()
+}
+
+func main() {
+
+ var ztsUrl, zmsUrl, ztsPublicKey, zmsPublicKey , outputFile string
+ flag.StringVar(&zmsUrl,"z", "", "Base URL of the ZMS server to use")
+ flag.StringVar(&ztsUrl, "t", "", "Base URL of the ZTS server to use")
+ flag.StringVar(&zmsPublicKey, "k", "", "Public key file of ZMS server to use")
+ flag.StringVar(&ztsPublicKey, "e", "", "Public key file of ZTS server to use")
+ flag.StringVar(&outputFile, "o", "/opt/zts/conf/athenz.conf", "The output athenz conf file")
+ flag.Usage = func() {
+ fmt.Println(usage())
+ }
+
+ flag.Parse()
+
+ if zmsUrl == "" || zmsPublicKey == "" {
+ fmt.Println(usage())
+ log.Fatalf("zms url and key flags are mandatory")
+ }
+
+ if (ztsUrl == "" && ztsPublicKey != "" )|| (ztsUrl != "" && ztsPublicKey == ""){
+ fmt.Println(usage())
+ log.Fatalf("Both zts url and key should be passed")
+ }
+
+ byte, err := ioutil.ReadFile(zmsPublicKey)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ zmsKey := new(zmssvctoken.YBase64).EncodeToString(byte)
+
+ var ztsKey string
+ if ztsPublicKey != ""{
+ byte, err = ioutil.ReadFile(ztsPublicKey)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ ztsKey = new(zmssvctoken.YBase64).EncodeToString(byte)
+ }
+
+
+ var buf bytes.Buffer
+ buf.WriteString("{\n")
+ buf.WriteString("\"zmsUrl\": \"" + zmsUrl + "\",\n")
+ buf.WriteString("\"ztsUrl\": \"" + ztsUrl + "\",\n")
+ buf.WriteString("\"ztsPublicKeys\": [\n")
+ buf.WriteString(" {\n")
+ buf.WriteString(" \"id\": \"0\",\n")
+ buf.WriteString(" \"key\": \"" + ztsKey + "\"\n")
+ buf.WriteString(" }")
+ buf.WriteString("\n")
+ buf.WriteString("], \n")
+ buf.WriteString("\"zmsPublicKeys\": [\n")
+ buf.WriteString(" {\n")
+ buf.WriteString(" \"id\": \"0\",\n")
+ buf.WriteString(" \"key\": \"" + zmsKey + "\"\n")
+ buf.WriteString(" }")
+ buf.WriteString("\n")
+ buf.WriteString("]")
+ buf.WriteString("\n")
+ buf.WriteString("}\n")
+
+ err = ioutil.WriteFile(outputFile, buf.Bytes(), 0644)
+ if err != nil {
+ log.Fatalf("Unable to write athenz.conf file, err: %v", err)
+ }
+ os.Exit(0)
+
+}
\ No newline at end of file
diff --git a/aws-setup/athenz-conf-aws/pom.xml b/aws-setup/athenz-conf-aws/pom.xml
new file mode 100755
index 00000000000..b5e451332cf
--- /dev/null
+++ b/aws-setup/athenz-conf-aws/pom.xml
@@ -0,0 +1,71 @@
+
+
+
+ 4.0.0
+
+
+ com.yahoo.athenz
+ athenz
+ 1.7.52-SNAPSHOT
+ ../../pom.xml
+
+
+ athenz-conf-aws
+ jar
+ athenz-conf-aws
+ Athenz Config File Utility
+
+
+ true
+ true
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.1.1
+
+
+
+ exec
+
+ compile
+
+
+
+ make
+
+ PKG_VERSION=${project.parent.version}
+ clean
+ all
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.4
+
+
+ default-jar
+
+
+
+
+
+
+
+
diff --git a/aws-setup/cloud-formation/packer_vpc.yaml b/aws-setup/cloud-formation/packer_vpc.yaml
new file mode 100755
index 00000000000..1001a649a2d
--- /dev/null
+++ b/aws-setup/cloud-formation/packer_vpc.yaml
@@ -0,0 +1,316 @@
+AWSTemplateFormatVersion: 2010-09-09
+Description: 'Athenz packer standard 2 Availabilty zone configuration template'
+Parameters:
+ packerVPCCidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the VPC.
+ Default: "10.0.0.0/24"
+ PrivateSubnet01CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the VPC.
+ Default: "10.0.0.0/26"
+ PublicSubnet01CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the VPC.
+ Default: "10.0.0.64/26"
+ Environment:
+ Type: String
+ Description: The environment packer is running in
+ AllowedValues:
+ - prod
+ - stage
+ - dev
+Resources:
+ packerVPC:
+ Type: 'AWS::EC2::VPC'
+ Properties:
+ CidrBlock: !Ref 'packerVPCCidrBlock'
+ EnableDnsSupport: true
+ EnableDnsHostnames: true
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-packer
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet01:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PrivateSubnet01CidrBlock'
+ VpcId: !Ref 'packerVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-packer-${AWS::Region}-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet01:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PublicSubnet01CidrBlock'
+ VpcId: !Ref 'packerVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-packer-${AWS::Region}-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ Nacl:
+ Type: "AWS::EC2::NetworkAcl"
+ Properties:
+ VpcId: !Ref 'packerVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-packer
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ NetworkAclEntry01:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '100'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: !Ref 'packerVPCCidrBlock'
+ PortRange:
+ From: '22'
+ To: '22'
+ NetworkAclEntry02:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '110'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '8443'
+ To: '8443'
+ NetworkAclEntry03:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '120'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '80'
+ To: '80'
+ NetworkAclEntry04:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '130'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '443'
+ To: '443'
+ NetworkAclEntry05:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '140'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '1024'
+ To: '65535'
+ NetworkAclEntry06:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '150'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '8080'
+ To: '8080'
+ NetworkAclEntry07:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '100'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '22'
+ To: '22'
+ NetworkAclEntry08:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '110'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '8443'
+ To: '8443'
+ NetworkAclEntry09:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '120'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '80'
+ To: '80'
+ NetworkAclEntry10:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '130'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '443'
+ To: '443'
+ NetworkAclEntry11:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '140'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '1024'
+ To: '65535'
+ NetworkAclEntry12:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '150'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '8080'
+ To: '8080'
+ PrivateSubnet01Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PrivateSubnet01'
+ NetworkAclId: !Ref 'Nacl'
+ PublicSubnet01Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PublicSubnet01'
+ NetworkAclId: !Ref 'Nacl'
+ InternetGateway:
+ Type: "AWS::EC2::InternetGateway"
+ Properties:
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-packer
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ VPCGatewayAttachment:
+ Type: "AWS::EC2::VPCGatewayAttachment"
+ Properties:
+ InternetGatewayId: !Ref 'InternetGateway'
+ VpcId: !Ref 'packerVPC'
+ PublicSubnet01NatGateway:
+ Type: "AWS::EC2::NatGateway"
+ Properties:
+ AllocationId: !GetAtt PublicSubnet01EIP.AllocationId
+ SubnetId: !Ref 'PublicSubnet01'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-packer-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet01EIP:
+ DependsOn: VPCGatewayAttachment
+ Type: AWS::EC2::EIP
+ Properties:
+ Domain: vpc
+ PublicSubnetRouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'packerVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-packer-${AWS::Region}-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ GatewayRoute:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ GatewayId: !Ref 'InternetGateway'
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ DependsOn: VPCGatewayAttachment
+ PrivateSubnet01RouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'packerVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-packer-${AWS::Region}-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet01Route:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ NatGatewayId: !Ref 'PublicSubnet01NatGateway'
+ RouteTableId: !Ref 'PrivateSubnet01RouteTable'
+ PublicSubnet01RouteTableAssociaton:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ SubnetId: !Ref 'PublicSubnet01'
+ PrivateSubnet01RouteTableAssociation:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PrivateSubnet01RouteTable'
+ SubnetId: !Ref 'PrivateSubnet01'
\ No newline at end of file
diff --git a/aws-setup/ui-setup/build/bin/athenz_conf.sh b/aws-setup/ui-setup/build/bin/athenz_conf.sh
new file mode 100755
index 00000000000..40076927991
--- /dev/null
+++ b/aws-setup/ui-setup/build/bin/athenz_conf.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+#############
+# Usage: athenz_conf.sh [outputFile] [zts key bucket path] [zts url] [zms key bucket path] [zms url]
+# Generates Athenz conf file
+###############
+
+displayUsage() {
+ echo "athenz_conf.sh [outputFile] [uiDataBucketName][zmsUrl]";
+ echo 'athenz_conf.sh ./output.json athenz-zts-data-us-west-2 https://zms.athenz.com:4443/';
+}
+
+if [ $# -ne 3 ]
+then
+ displayUsage
+ exit 1
+fi
+
+zms_public_key_file=zms_service_x509_key_public.pem
+
+
+outputFile=$1
+dataBucketName=$2
+zmsUrl=$3
+
+# download CA certs from S3 bucket and store locally in temp directory
+aws s3 cp s3://$dataBucketName/$zms_public_key_file /tmp/zms_pub_key
+
+sudo /opt/athenz-ui/bin/linux/athenz-conf-aws -z $zmsUrl -k /tmp/zms_pub_key -o $outputFile
diff --git a/aws-setup/ui-setup/build/bin/aws_config.sh b/aws-setup/ui-setup/build/bin/aws_config.sh
new file mode 100755
index 00000000000..0ab33023c9a
--- /dev/null
+++ b/aws-setup/ui-setup/build/bin/aws_config.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+aws_config_dir="$HOME/.aws"
+
+if [ -z "$HOME" ]; then
+ aws_config_dir="/athenz-zts/.aws"
+fi
+
+echo "Configuring aws config in $aws_config_dir"
+
+if [ ! -d "$aws_config_dir" ]; then
+ mkdir $aws_config_dir
+fi
+
+aws_config="[default]\nregion=$REGION"
+echo -e $aws_config > $aws_config_dir/config
diff --git a/aws-setup/ui-setup/build/bin/get_certs.sh b/aws-setup/ui-setup/build/bin/get_certs.sh
new file mode 100755
index 00000000000..922f3720a8b
--- /dev/null
+++ b/aws-setup/ui-setup/build/bin/get_certs.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+# download server cert and key from private s3 bucket
+# aws s3 client will automatically decrypt the data
+
+BUCKET_NAME=$1
+KEY_FILE=service_x509_key
+CERT_FILE=service_x509_cert
+SERVICE_PRIVATE_KEY_FILE=service_private_key
+ZMS_CA_CERT_FILE=zms_service_x509_ca_certs
+
+sudo mkdir -p /opt/athenz-ui/keys
+aws s3 cp s3://$BUCKET_NAME/$KEY_FILE /opt/athenz-ui/keys/ui_key.pem
+aws s3 cp s3://$BUCKET_NAME/$CERT_FILE /opt/athenz-ui/keys/ui_cert.pem
+aws s3 cp s3://$BUCKET_NAME/$SERVICE_PRIVATE_KEY_FILE /opt/athenz-ui/keys/athenz.ui.pem
+openssl rsa -in /opt/athenz-ui/keys/athenz.ui.pem -pubout > /opt/athenz-ui/keys/athenz.ui_pub.pem
+aws s3 cp s3://$BUCKET_NAME/$ZMS_CA_CERT_FILE /opt/athenz-ui/keys/zms_cert.pem
\ No newline at end of file
diff --git a/aws-setup/ui-setup/build/bin/ui.sh b/aws-setup/ui-setup/build/bin/ui.sh
new file mode 100755
index 00000000000..1cd6b7355ee
--- /dev/null
+++ b/aws-setup/ui-setup/build/bin/ui.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+set -e
+
+echo "========= Getting region and env from AWS ========="
+
+REGION=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/.$//')
+ENV="dev"
+BUCKET_NAME=test-athenz-ui-data-bucket
+ATHENZ_CONF_PATH=/opt/athenz-ui/conf/athenz.conf
+
+export ENVIRONMENT="${ENV}"
+export REGION="${REGION}"
+export UI_SERVER="test.ui.athens.aws.oath.cloud"
+export ZMS_SERVER="test.athens.aws.oath.cloud"
+export ZMS_SERVER_URL="https://${ZMS_SERVER}:4443/zms/v1/"
+export ROOT=/opt
+
+echo "initializing aws cloudwatch log setup"
+sudo python /opt/athenz-ui/logs/awslogs-agent-setup.py -n -r $REGION -c /opt/athenz-ui/conf/awslogs.conf
+
+echo "generating athenz conf"
+/opt/athenz-ui/bin/athenz_conf.sh $ATHENZ_CONF_PATH $BUCKET_NAME $ZMS_SERVER
+
+echo "Downloading certs and keys from s3 bucket"
+/opt/athenz-ui/bin/get_certs.sh $BUCKET_NAME
+
+echo "Starting UI Server"
+/bin/node /opt/athenz-ui/server.js
+echo "UI server running at 443"
\ No newline at end of file
diff --git a/aws-setup/ui-setup/build/conf/awslogs.conf b/aws-setup/ui-setup/build/conf/awslogs.conf
new file mode 100755
index 00000000000..9abc27b54a5
--- /dev/null
+++ b/aws-setup/ui-setup/build/conf/awslogs.conf
@@ -0,0 +1,8 @@
+[general]
+state_file = /var/awslogs/state/agent-state
+
+[syslog]
+file = /var/log/messages
+log_group_name = athenz-ui-service
+log_stream_name = {instance_id}
+datetime_format = %b %d %H:%M:%S
\ No newline at end of file
diff --git a/aws-setup/ui-setup/build/conf/ui-user b/aws-setup/ui-setup/build/conf/ui-user
new file mode 100755
index 00000000000..6cdff8f4320
--- /dev/null
+++ b/aws-setup/ui-setup/build/conf/ui-user
@@ -0,0 +1 @@
+athenz-ui ALL=(ALL) NOPASSWD: ALL
\ No newline at end of file
diff --git a/aws-setup/ui-setup/build/service/ui.service b/aws-setup/ui-setup/build/service/ui.service
new file mode 100755
index 00000000000..fd2e6e52625
--- /dev/null
+++ b/aws-setup/ui-setup/build/service/ui.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Athens UI
+Wants=network-online.target ntpd.service
+After=network-online.target
+
+[Service]
+StandardOutput=syslog
+StandardError=syslog
+SyslogIdentifier=athenz-ui
+Restart=on-failure
+RestartSec=20
+ExecStart=/opt/athenz-ui/bin/ui.sh
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/aws-setup/ui-setup/cloud-formation/athens-ui-aws-instance-deployment.yaml b/aws-setup/ui-setup/cloud-formation/athens-ui-aws-instance-deployment.yaml
new file mode 100755
index 00000000000..e6aa53c6b00
--- /dev/null
+++ b/aws-setup/ui-setup/cloud-formation/athens-ui-aws-instance-deployment.yaml
@@ -0,0 +1,127 @@
+Description: 'Athenz UI standard 2 Availabilty zone instance deployment template'
+Parameters:
+ ServiceRole:
+ Type: String
+ Description: The UI Service IAM Role Name
+ Default: "athenz.ui-service"
+ KeyName:
+ Type: String
+ Description: The EC2 key pair for the instance
+ ServiceName:
+ Type: String
+ Description: The service name for UI server
+ Default: "ui"
+ ResourceStackName:
+ Type: String
+ Description: Name of Stack used to create AWS Resources
+ Environment:
+ Type: String
+ Description: The environment UI is running in
+ AllowedValues:
+ - prod
+ - stage
+ - dev
+ ImageId:
+ Type: AWS::EC2::Image::Id
+ Description: "The ImageId to use for the EC2 instance. Should be a format like ami-XXXXXXXX"
+ AutoScalingMinSize:
+ Type: String
+ Description: The minimum instances for auto scaling
+ Default: "2"
+ AutoScalingMaxSize:
+ Type: String
+ Description: The maximum instances for auto scaling
+ Default: "4"
+ AutoScalingDesiredCapacity:
+ Type: String
+ Description: The desired number of instances
+ Default: "2"
+ EbsOptimized:
+ Type: String
+ Description: If EBS is to be optimized
+ AllowedValues:
+ - "true"
+ - "false"
+ Default: "false"
+ Ec2InstanceType:
+ Type: String
+ Description: The instance type to use for the host
+ Default: t2.large
+ AllowedValues:
+ - t2.nano
+ - t2.micro
+ - t2.small
+ - t2.medium
+ - t2.large
+ - t2.xlarge
+ - t2.2xlarge
+ - m4.large
+ - m4.xlarge
+ - m4.2xlarge
+ - m4.4xlarge
+ - m4.10xlarge
+ - m4.16xlarge
+ - m5.large
+ - m5.xlarge
+ - m5.2xlarge
+ - m5.4xlarge
+ - m5.12xlarge
+ - m5.24xlarge
+ - m5d.large
+ - m5d.xlarge
+ - m5d.2xlarge
+ - m5d.4xlarge
+ - m5d.12xlarge
+ - m5d.24xlarge
+ EbsVolumeType:
+ Type: String
+ Description: The value for EBS Volume type in Block Device Mappings for Launch Configuration
+ Default: "gp2"
+ EbsVolumeSize:
+ Type: Number
+ Description: The value for EBS Volume size Block Device Mappings for Launch Configuration
+ Default: "50"
+Resources:
+ UIEC2AutoScalingGroup:
+ Type: 'AWS::AutoScaling::AutoScalingGroup'
+ Properties:
+ LaunchConfigurationName: !Ref UILaunchConfig
+ LoadBalancerNames:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-LoadBalancerName"
+ MaxSize: !Ref AutoScalingMaxSize
+ MinSize: !Ref AutoScalingMinSize
+ Cooldown: 300
+ VPCZoneIdentifier:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-PrivateSubnet01ID"
+ - Fn::ImportValue: !Sub "${ResourceStackName}-PrivateSubnet02ID"
+ DesiredCapacity: !Ref AutoScalingDesiredCapacity
+ HealthCheckGracePeriod: 900
+ HealthCheckType: ELB
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-asg-${ServiceName}-${AWS::Region}
+ PropagateAtLaunch: true
+ - Key: Environment
+ Value: !Ref Environment
+ PropagateAtLaunch: true
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PropagateAtLaunch: true
+ UILaunchConfig:
+ Type: 'AWS::AutoScaling::LaunchConfiguration'
+ Properties:
+ AssociatePublicIpAddress: false
+ IamInstanceProfile: !Sub arn:aws:iam::${AWS::AccountId}:instance-profile/${ServiceRole}
+ ImageId: !Ref ImageId
+ KeyName: !Ref KeyName
+ InstanceType: !Ref Ec2InstanceType
+ EbsOptimized: !Ref EbsOptimized
+ SecurityGroups:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-ServerSecurityGroupID"
+ BlockDeviceMappings:
+ - DeviceName: "/dev/sda1"
+ Ebs:
+ VolumeSize: !Ref EbsVolumeSize
+ VolumeType: !Ref EbsVolumeType
+ DeleteOnTermination: true
+ InstanceMonitoring: true
\ No newline at end of file
diff --git a/aws-setup/ui-setup/cloud-formation/athens-ui-aws-resource-setup.yaml b/aws-setup/ui-setup/cloud-formation/athens-ui-aws-resource-setup.yaml
new file mode 100755
index 00000000000..b730594e239
--- /dev/null
+++ b/aws-setup/ui-setup/cloud-formation/athens-ui-aws-resource-setup.yaml
@@ -0,0 +1,555 @@
+AWSTemplateFormatVersion: 2010-09-09
+Description: 'Athenz UI standard 2 Availabilty zone configuration template'
+Parameters:
+ UIServiceName:
+ Type: String
+ Description: The service name for UI server
+ Default: "ui"
+ UIVPCCidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the UI VPC.
+ Default: "10.0.0.0/20"
+ PrivateSubnet01CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Private subnet Zone 1.
+ Default: "10.0.0.0/22"
+ PrivateSubnet02CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Private subnet Zone 2.
+ Default: "10.0.4.0/22"
+ PublicSubnet01CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for Public subnet Zone 1.
+ Default: "10.0.8.0/22"
+ PublicSubnet02CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for Public subnet Zone 2.
+ Default: "10.0.12.0/22"
+ GroupName:
+ Type: String
+ Description: The Athens domain for the account
+ Default: "Athenz"
+ Environment:
+ Type: String
+ Description: The environment UI is running in
+ AllowedValues:
+ - prod
+ - stage
+ - dev
+ S3AccessLogBucketName:
+ Type: String
+ Description: S3 bucket name to store access logs
+ Route53HostedZoneName:
+ Type: String
+ Description: The hosted zone name to place a CNAME entry for. Must end with a period. Empty string means do not create one.
+ Route53RecordName:
+ Type: String
+ Description: The hosted records to be added
+Conditions:
+ CreateDNSRecordSet: !Not [!Equals [ !Ref Route53HostedZoneName, '']]
+
+
+Resources:
+ UIVPC:
+ Type: 'AWS::EC2::VPC'
+ Properties:
+ CidrBlock: !Ref 'UIVPCCidrBlock'
+ EnableDnsSupport: true
+ EnableDnsHostnames: true
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet01:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PrivateSubnet01CidrBlock'
+ VpcId: !Ref 'UIVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}-${AWS::Region}a-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet02:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 1
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PrivateSubnet02CidrBlock'
+ VpcId: !Ref 'UIVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}-${AWS::Region}b-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet01:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PublicSubnet01CidrBlock'
+ VpcId: !Ref 'UIVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}-${AWS::Region}a-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet02:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 1
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PublicSubnet02CidrBlock'
+ VpcId: !Ref 'UIVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}-${AWS::Region}b-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ Nacl:
+ Type: "AWS::EC2::NetworkAcl"
+ Properties:
+ VpcId: !Ref 'UIVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ NetworkAclEntry01:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '100'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: !Ref 'UIVPCCidrBlock'
+ PortRange:
+ From: '22'
+ To: '22'
+ NetworkAclEntry02:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '110'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '2222'
+ To: '2222'
+ NetworkAclEntry03:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '120'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '80'
+ To: '80'
+ NetworkAclEntry04:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '130'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '443'
+ To: '443'
+ NetworkAclEntry05:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '140'
+ Protocol: "17"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '123'
+ To: '123'
+ NetworkAclEntry06:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '200'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '1024'
+ To: '65535'
+ NetworkAclEntry07:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '100'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '22'
+ To: '22'
+ NetworkAclEntry08:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '110'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '2222'
+ To: '2222'
+ NetworkAclEntry09:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '120'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '80'
+ To: '80'
+ NetworkAclEntry10:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '130'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '443'
+ To: '443'
+ NetworkAclEntry11:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '140'
+ Protocol: "17"
+ RuleAction: allow
+ CidrBlock: !Ref 'UIVPCCidrBlock'
+ PortRange:
+ From: '123'
+ To: '123'
+ NetworkAclEntry12:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '200'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '1024'
+ To: '65535'
+ PrivateSubnet01Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PrivateSubnet01'
+ NetworkAclId: !Ref 'Nacl'
+ PrivateSubnet02Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PrivateSubnet02'
+ NetworkAclId: !Ref 'Nacl'
+ PublicSubnet01Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PublicSubnet01'
+ NetworkAclId: !Ref 'Nacl'
+ PublicSubnet02Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PublicSubnet02'
+ NetworkAclId: !Ref 'Nacl'
+ InternetGateway:
+ Type: "AWS::EC2::InternetGateway"
+ Properties:
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ VPCGatewayAttachment:
+ Type: "AWS::EC2::VPCGatewayAttachment"
+ Properties:
+ InternetGatewayId: !Ref 'InternetGateway'
+ VpcId: !Ref 'UIVPC'
+ PublicSubnet01NatGateway:
+ Type: "AWS::EC2::NatGateway"
+ Properties:
+ AllocationId: !GetAtt PublicSubnet01EIP.AllocationId
+ SubnetId: !Ref 'PublicSubnet01'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}-${AWS::Region}a
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet01EIP:
+ DependsOn: VPCGatewayAttachment
+ Type: AWS::EC2::EIP
+ Properties:
+ Domain: vpc
+ PublicSubnet02NatGateway:
+ Type: "AWS::EC2::NatGateway"
+ Properties:
+ AllocationId: !GetAtt PublicSubnet02EIP.AllocationId
+ SubnetId: !Ref 'PublicSubnet02'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}-${AWS::Region}b
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet02EIP:
+ DependsOn: VPCGatewayAttachment
+ Type: AWS::EC2::EIP
+ Properties:
+ Domain: vpc
+ PublicSubnetRouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'UIVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}-${AWS::Region}-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ GatewayRoute:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ GatewayId: !Ref 'InternetGateway'
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ DependsOn: VPCGatewayAttachment
+ PrivateSubnet01RouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'UIVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}-${AWS::Region}a-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet01Route:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ NatGatewayId: !Ref 'PublicSubnet01NatGateway'
+ RouteTableId: !Ref 'PrivateSubnet01RouteTable'
+ PrivateSubnet02RouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'UIVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${UIServiceName}-${AWS::Region}b-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet02Route:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ NatGatewayId: !Ref 'PublicSubnet02NatGateway'
+ RouteTableId: !Ref 'PrivateSubnet02RouteTable'
+ DependsOn: VPCGatewayAttachment
+ PublicSubnet01RouteTableAssociaton:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ SubnetId: !Ref 'PublicSubnet01'
+ PublicSubnet02RouteTableAssociaton:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ SubnetId: !Ref 'PublicSubnet02'
+ PrivateSubnet01RouteTableAssociation:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PrivateSubnet01RouteTable'
+ SubnetId: !Ref 'PrivateSubnet01'
+ PrivateSubnet02RouteTableAssociation:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PrivateSubnet02RouteTable'
+ SubnetId: !Ref 'PrivateSubnet02'
+ UIELBSecurityGroup:
+ Type: "AWS::EC2::SecurityGroup"
+ Properties:
+ GroupName: !Sub ${GroupName}-${Environment}-elb-sg-${UIServiceName}-${AWS::Region}
+ GroupDescription: 'UI public elb security group'
+ SecurityGroupIngress:
+ - IpProtocol: tcp
+ FromPort: '443'
+ ToPort: '443'
+ CidrIp: '0.0.0.0/0'
+ VpcId: !Ref 'UIVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-elb-${UIServiceName}-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ UIServerSecurityGroup:
+ Type: "AWS::EC2::SecurityGroup"
+ Properties:
+ GroupName: !Sub ${GroupName}-${Environment}-server-sg-${UIServiceName}-${AWS::Region}
+ GroupDescription: 'UI public server security group'
+ SecurityGroupIngress:
+ - IpProtocol: tcp
+ FromPort: '443'
+ ToPort: '443'
+ CidrIp: '0.0.0.0/0'
+ - IpProtocol: tcp
+ FromPort: '8443'
+ ToPort: '8443'
+ CidrIp: !Ref 'UIVPCCidrBlock'
+ VpcId: !Ref 'UIVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-server-${UIServiceName}-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ UILoadBalancer:
+ Type: "AWS::ElasticLoadBalancing::LoadBalancer"
+ Properties:
+ HealthCheck:
+ HealthyThreshold: 2
+ Interval: 5
+ Target: TCP:443
+ Timeout: 2
+ UnhealthyThreshold: 4
+ Listeners:
+ - InstancePort: 443
+ InstanceProtocol: TCP
+ LoadBalancerPort: 443
+ Protocol: TCP
+ LoadBalancerName: !Sub ${Environment}-elb-${UIServiceName}-${AWS::Region}
+ Scheme: 'internet-facing'
+ ConnectionDrainingPolicy:
+ Enabled: 'true'
+ Timeout: '60'
+ CrossZone: true
+ SecurityGroups:
+ - !Ref UIELBSecurityGroup
+ Subnets:
+ - !Ref 'PublicSubnet01'
+ - !Ref 'PublicSubnet02'
+ AccessLoggingPolicy:
+ S3BucketName: !Ref S3AccessLogBucketName
+ S3BucketPrefix: !Sub elb-${UIServiceName}
+ Enabled: 'true'
+ EmitInterval: '5'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-elb-UI-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ UIRecordSet:
+ Type: AWS::Route53::RecordSet
+ Condition: CreateDNSRecordSet
+ Properties:
+ Comment: CNAME record for the UI Server.
+ HostedZoneName: !Ref Route53HostedZoneName
+ Name: !Ref Route53RecordName
+ TTL: 60
+ Type: CNAME
+ ResourceRecords:
+ - !GetAtt UILoadBalancer.DNSName
+Outputs:
+ UIVPCID:
+ Description: The ID of the UI VPC
+ Value: !Ref UIVPC
+ Export:
+ Name: !Sub "${AWS::StackName}-VPCID"
+ PrivateSubnet01ID:
+ Description: TThe ID of Private Subnet Availability Zone 1 in UI VPC
+ Value: !Ref PrivateSubnet01
+ Export:
+ Name: !Sub "${AWS::StackName}-PrivateSubnet01ID"
+ PrivateSubnet02ID:
+ Description: The ID of Private Subnet Availability Zone 2 in UI VPC
+ Value: !Ref PrivateSubnet02
+ Export:
+ Name: !Sub "${AWS::StackName}-PrivateSubnet02ID"
+ LoadBalancerName :
+ Description: The name of UI Load Balancer
+ Value: !Ref UILoadBalancer
+ Export:
+ Name: !Sub "${AWS::StackName}-LoadBalancerName"
+ ServerSecurityGroupID:
+ Description: TThe ID of UI Server security group
+ Value: !Ref UIServerSecurityGroup
+ Export:
+ Name: !Sub "${AWS::StackName}-ServerSecurityGroupID"
+
diff --git a/aws-setup/ui-setup/cloud-formation/athens-ui-aws-roles-setup.yaml b/aws-setup/ui-setup/cloud-formation/athens-ui-aws-roles-setup.yaml
new file mode 100755
index 00000000000..201a8f1f01c
--- /dev/null
+++ b/aws-setup/ui-setup/cloud-formation/athens-ui-aws-roles-setup.yaml
@@ -0,0 +1,46 @@
+AWSTemplateFormatVersion: 2010-09-09
+Description: Roles needed for athens ui setup
+Parameters:
+ AthensServiceRole:
+ Type: String
+ Description: The Athens role name for the service
+ Default: athenz.ui-service
+Resources:
+ AthensServiceEC2Role:
+ Type: "AWS::IAM::Role"
+ Properties:
+ AssumeRolePolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ -
+ Effect: "Allow"
+ Principal:
+ Service:
+ - "ec2.amazonaws.com"
+ Action:
+ - "sts:AssumeRole"
+ Policies:
+ -
+ PolicyName: !Sub ${AthensServiceRole}.policy
+ PolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ - Effect: "Allow"
+ Action:
+ - logs:CreateLogGroup
+ - logs:CreateLogStream
+ - logs:PutLogEvents
+ - logs:DescribeLogStreams
+ - logs:DescribeLogGroups
+ Resource: "arn:aws:logs:*:*:*"
+ - Effect: "Allow"
+ Action: "ec2:DescribeTags"
+ Resource: "*"
+ Path: /
+ RoleName: !Ref AthensServiceRole
+ AthensEc2InstanceProfile:
+ Type: "AWS::IAM::InstanceProfile"
+ Properties:
+ Roles:
+ - !Ref AthensServiceEC2Role
+ InstanceProfileName: !Ref AthensServiceRole
\ No newline at end of file
diff --git a/aws-setup/ui-setup/packer/aws/packer.json b/aws-setup/ui-setup/packer/aws/packer.json
new file mode 100755
index 00000000000..da3f02fa80d
--- /dev/null
+++ b/aws-setup/ui-setup/packer/aws/packer.json
@@ -0,0 +1,99 @@
+{
+ "variables": {
+ "subnet_id":"subnet-xxxxxxxx",
+ "vpc_id": "vpc-xxxxxxxxxxxxx",
+ "aws_region": "{{env `AWS_REGION`}}",
+ "aws_ami_name": "ui-aws-cd-image",
+ "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
+ "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}",
+ "aws_session_token": "{{env `AWS_SESSION_TOKEN`}}",
+ "ssh_keypair_name":"keypair-name",
+ "ssh_private_key_file":"path to ssh key file",
+ "source_ami": "ami-02c71d7a"
+ },
+ "builders": [
+ {
+ "access_key": "{{user `aws_access_key`}}",
+ "secret_key": "{{user `aws_secret_key`}}",
+ "token": "{{user `aws_session_token`}}",
+ "name": "amazon-ebs",
+ "ssh_username": "centos",
+ "ssh_keypair_name":"{{user `ssh_keypair_name`}}",
+ "ssh_private_key_file":"{{user `ssh_private_key_file`}}",
+ "type": "amazon-ebs",
+ "region": "{{user `aws_region`}}",
+ "source_ami": "{{user `source_ami`}}",
+ "ami_block_device_mappings": [
+ {
+ "device_name": "/dev/sda1",
+ "volume_type": "gp2",
+ "volume_size": 50,
+ "encrypted": true,
+ "delete_on_termination": true
+ }
+ ],
+ "encrypt_boot": true,
+ "instance_type": "t2.micro",
+ "ami_name": "{{user `aws_ami_name`}}",
+ "ami_description": "UI Image for cloud formation",
+ "associate_public_ip_address": "true",
+ "subnet_id": "{{ user `subnet_id` }}",
+ "vpc_id": "{{ user `vpc_id` }}"
+ }],
+
+ "provisioners": [
+ {
+ "type": "shell",
+ "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
+ "inline": [
+ "mkdir -p /opt",
+ "chmod a+w /opt"
+ ]
+ },
+ {
+ "type": "file",
+ "source": "tars/",
+ "destination": "/opt/"
+ },
+ {
+ "type": "shell",
+ "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
+ "inline": [
+ "sudo tar -xzf /opt/athenz-ui-bin.tar.gz -C /opt/",
+ "sudo chmod 777 /opt/athenz-ui",
+ "mkdir -p /opt/athenz-ui/conf",
+ "mkdir -p /opt/athenz-ui/logs",
+ "sudo chmod 777 /opt/athenz-ui -R"
+ ]
+ },
+ {
+ "type": "file",
+ "source": "build/bin/",
+ "destination": "/opt/athenz-ui/bin/"
+ },
+ {
+ "type": "file",
+ "source": "build/conf/",
+ "destination": "/opt/athenz-ui/conf/"
+ },
+ {
+ "type": "file",
+ "source": "build/service/",
+ "destination": "/opt/athenz-ui/"
+ },
+ {
+ "type": "shell",
+ "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
+ "inline": [
+ "ls -ltr /opt/"
+ ]
+ },
+ {
+ "type": "shell",
+ "scripts": [
+ "packer/scripts/setup.sh"
+ ],
+ "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E '{{ .Path }}'"
+ }
+ ]
+}
diff --git a/aws-setup/ui-setup/packer/scripts/setup.sh b/aws-setup/ui-setup/packer/scripts/setup.sh
new file mode 100755
index 00000000000..ccb3044c6a4
--- /dev/null
+++ b/aws-setup/ui-setup/packer/scripts/setup.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+set -xe
+
+# install epel
+
+sudo yum repolist
+sudo yum -y install epel-release
+
+
+# install aws_cli
+
+echo "install aws"
+sudo yum -y install python-pip
+sudo pip install awscli
+aws --version
+
+# install node
+
+sudo curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash -
+sudo yum -y install nodejs
+
+# setup our athenz group and user
+
+sudo groupadd athenz
+sudo useradd -g athenz athenz-ui
+
+# setup our ui service
+
+sudo mkdir /etc/ui
+sudo cp /opt/athenz-ui/ui.service /etc/ui/ui.service
+sudo systemctl enable /etc/ui/ui.service
+sudo cp /opt/athenz-ui/conf/ui-user /etc/sudoers.d/
+
+#set up aws logs
+
+curl https://s3.amazonaws.com//aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -o /opt/athenz-ui/logs/awslogs-agent-setup.py
+
+# make sure all files are owned by our user/group
+
+sudo chown -R athenz-ui:athenz /opt/athenz-ui
diff --git a/aws-setup/zms-setup/build/bin/add_user.sh b/aws-setup/zms-setup/build/bin/add_user.sh
new file mode 100755
index 00000000000..538465fc01b
--- /dev/null
+++ b/aws-setup/zms-setup/build/bin/add_user.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+displayUsage() {
+ echo "add_user.sh [username] [bucket_name] ";
+}
+
+if [ $# -ne 2 ]
+then
+ displayUsage
+ exit 1
+fi
+
+adminUser=$1
+bucketName=$2
+passFile=/tmp/admin_pass
+
+aws s3 cp s3://$bucketName/admin_pass $passFile
+adminPass=$(cat $passFile)
+
+sudo useradd $adminUser
+echo $adminPass | sudo passwd $adminUser --stdin
+
+sudo rm $passFile
\ No newline at end of file
diff --git a/aws-setup/zms-setup/build/bin/aws_config.sh b/aws-setup/zms-setup/build/bin/aws_config.sh
new file mode 100755
index 00000000000..3dcb21a48c7
--- /dev/null
+++ b/aws-setup/zms-setup/build/bin/aws_config.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+aws_config_dir="$HOME/.aws"
+
+if [ -z "$HOME" ]; then
+ aws_config_dir="/athenz-zms/.aws"
+fi
+
+echo "Configuring aws config in $aws_config_dir"
+
+if [ ! -d "$aws_config_dir" ]; then
+ mkdir $aws_config_dir
+fi
+
+aws_config="[default]\nregion=$REGION"
+echo -e $aws_config > $aws_config_dir/config
+
+aws configure set s3.signature_version s3v4
diff --git a/aws-setup/zms-setup/build/bin/aws_init.sh b/aws-setup/zms-setup/build/bin/aws_init.sh
new file mode 100755
index 00000000000..049aac823b5
--- /dev/null
+++ b/aws-setup/zms-setup/build/bin/aws_init.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# Exposes bucket names based on account and region
+# ENV
+# ZMS_DATA_BUCKET_NAME
+# ZMS_AUDIT_LOG_BUCKET_NAME
+# REGION
+# TRUST_STORE_PATH
+# JDK_CA_CERTS_PATH
+# KEY_STORE_PATH
+# JDK_CA_CERTS_PWD
+# RDS_MASTER
+# RDS_REPLICA
+
+set -e
+
+export REGION=`curl http://169.254.169.254/latest/dynamic/instance-identity/document|grep region|awk -F\" '{print $4}'`
+export ENV="dev"
+
+export ZMS_DATA_BUCKET_NAME="athenz-zms-data-bucket-name"
+export ZMS_AUDIT_LOG_BUCKET_NAME="athenz-audit-log-bucket-name"
+export DOMAIN_ADMIN="zms-admin"
+export RDS_MASTER="zms-rds-database-cluster-endpoint"
+export TRUST_STORE_PATH="/opt/zms/conf/zms_java_truststore.jks"
+export ZMS_TRUST_STORE_PATH="/opt/zms/conf/zms_truststore.jks"
+export JDK_CA_CERTS_PATH="/etc/alternatives/jre_1.8.0_openjdk/lib/security/cacerts"
+export KEY_STORE_PATH="/opt/zms/conf/zms_keystore.pkcs12"
+export JDK_CA_CERTS_PWD="changeit"
+export DATASTORE_NAME="zmsserver"
+
+
diff --git a/aws-setup/zms-setup/build/bin/aws_java_truststore_gen.sh b/aws-setup/zms-setup/build/bin/aws_java_truststore_gen.sh
new file mode 100755
index 00000000000..6e6c8d9e2f8
--- /dev/null
+++ b/aws-setup/zms-setup/build/bin/aws_java_truststore_gen.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+#############
+# Usage: aws_java_truststore_gen.sh [jdk-ca-certs-path] [jdk-ca-certs-pwd] [bucket name] [trust store path]
+# Downloads CA certs from S3 bucket. Creates pkcs12 truststore for jetty.
+# Check for generated truststore: openssl pkcs12 -info -in /opt/zms/conf/ca.pkcs12
+###############
+
+display_usage() {
+ echo "aws_java_truststore_gen.sh [jdk-ca-certs-path] [jdk-ca-certs-pwd] [bucket name] [trust store path]";
+ echo "example: aws_java_truststore_gen.sh /opt/jvm/cacerts changeit oath-aws-athenz-sys-auth-certsign-us-west-2 /opt/zms/conf/ca.pkcs12"
+}
+
+cleanup() {
+ rm -f /tmp/service_rds_ca_certs
+ rm -f split_cacert-*
+}
+
+if [ $# -ne 4 ]
+then
+ display_usage
+ exit 1
+fi
+
+cleanup
+
+# define our S3 bucket filenames. we'll be using the same names
+# when we store files locally
+
+rds_ca_certs=service_rds_ca_certs
+
+jdk_ca_certs_path=$1
+jdk_ca_certs_pwd=$2
+bucket_name=$3
+trust_store_path=$4
+
+# download RDS CA certs from s3 bucket
+# aws s3 client will automatically decrypt the data
+
+aws s3 cp s3://$bucket_name/$rds_ca_certs /tmp/$rds_ca_certs
+
+# first copy the jdk ca certs into our given filename
+
+cp $jdk_ca_certs_path $trust_store_path
+rc=$?; if [[ $rc != 0 ]]; then cleanup; exit $rc; fi
+chmod u+w $trust_store_path
+
+# split the CA certs and add them to the truststore
+
+csplit -f split_cacert- -s -z /tmp/$rds_ca_certs '/^-----BEGIN CERTIFICATE-----/' {*}
+CERT_FILES=split_cacert-*
+for file in $CERT_FILES
+do
+ echo "Processing $file file..."
+ keytool -import -noprompt -alias $file -keystore $trust_store_path -file $file -storepass $jdk_ca_certs_pwd
+ rc=$?; if [[ $rc != 0 ]]; then cleanup; exit $rc; fi
+done
+
+cleanup
+
+echo "successfully generated trust store"
diff --git a/aws-setup/zms-setup/build/bin/aws_zms_keystore_gen.sh b/aws-setup/zms-setup/build/bin/aws_zms_keystore_gen.sh
new file mode 100755
index 00000000000..e84e70e2049
--- /dev/null
+++ b/aws-setup/zms-setup/build/bin/aws_zms_keystore_gen.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+#############
+# Usage: aws_zms_keystore_gen.sh [bucket name] [key store path]
+# Downloads encrypted server.key and server.cert from private S3 bucket.
+# Decrypts and creates pkcs12 keystore for jetty.
+# Assumes that this script runs on an instance with a role that has policy
+# set to allow kms decrypt and read access to private S3 bucket.
+# Check for generated keystore: openssl pkcs12 -info -in jetty.pkcs12
+###############
+
+display_usage() {
+ echo "aws_zms_keystore_gen.sh [bucket name] [key store path]";
+ echo "example: aws_zms_keystore_gen.sh oath-aws-athenz-sys-auth-zms-prod-data-us-west-2 jetty.pkcs12"
+}
+
+cleanup() {
+ rm -f /tmp/service_x509_*
+}
+
+if [ $# -ne 2 ]
+then
+ display_usage
+ exit 1
+fi
+
+cleanup
+
+# define our S3 bucket filenames. we'll be using the same names
+# when we store files locally
+
+key_file=service_x509_key
+cert_file=service_x509_cert
+pwd_file=service_x509_store_pwd
+
+bucket_name=$1
+key_store_path=$2
+
+# download server cert and key from private s3 bucket
+# aws s3 client will automatically decrypt the data
+
+aws s3 cp s3://$bucket_name/$key_file /tmp/$key_file
+aws s3 cp s3://$bucket_name/$cert_file /tmp/$cert_file
+
+# extract the password the keystore
+
+aws s3 cp s3://$bucket_name/$pwd_file /tmp/$pwd_file
+key_store_pass=`cat /tmp/$pwd_file`
+
+# generate pkcs12 keystore using openssl
+
+openssl pkcs12 -export -inkey /tmp/$key_file -in /tmp/$cert_file -out $key_store_path -password pass:$key_store_pass -noiter -nomaciter
+openssl_status=$?
+
+cleanup
+
+if [ ! $openssl_status -eq 0 ]; then
+ echo "failed to generate key store"
+ exit 1
+fi
+
+echo "successfully generated key store"
+
diff --git a/aws-setup/zms-setup/build/bin/aws_zms_truststore_gen.sh b/aws-setup/zms-setup/build/bin/aws_zms_truststore_gen.sh
new file mode 100755
index 00000000000..16b4d327b90
--- /dev/null
+++ b/aws-setup/zms-setup/build/bin/aws_zms_truststore_gen.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+#############
+# Usage: aws_zms_truststore_gen.sh [bucket name] [trust store path]
+# Downloads CA certs from S3 bucket. Creates pkcs12 truststore for jetty.
+# Check for generated truststore: openssl pkcs12 -info -in /opt/zms/conf/ca.pkcs12
+###############
+
+display_usage() {
+ echo "aws_zms_truststore_gen.sh [bucket name] [trust store path]";
+ echo "example: aws_zms_truststore_gen.sh oath-aws-athenz-sys-auth-certsign-us-west-2 /opt/zms/conf/ca.pkcs12"
+}
+
+cleanup() {
+ rm -f /tmp/service_x509_ca_certs
+ rm -f split_cacert-*
+}
+
+if [ $# -ne 2 ]
+then
+ display_usage
+ exit 1
+fi
+
+cleanup
+
+# define our S3 bucket filenames. we'll be using the same names
+# when we store files locally
+
+ca_certs_file=service_x509_ca_certs
+pwd_file=service_x509_store_pwd
+
+bucket_name=$1
+trust_store_path=$2
+
+# download CA certs from s3 bucket
+# aws s3 client will automatically decrypt the data
+
+aws s3 cp s3://$bucket_name/$ca_certs_file /tmp/$ca_certs_file
+
+# extract the password the truststore
+
+aws s3 cp s3://$bucket_name/$pwd_file /tmp/$pwd_file
+trust_store_pass=`cat /tmp/$pwd_file`
+
+# split the CA certs and add them to the truststore
+
+csplit -f split_cacert- -s -z /tmp/$ca_certs_file '/^-----BEGIN CERTIFICATE-----/' {*}
+CERT_FILES=split_cacert-*
+for file in $CERT_FILES
+do
+ echo "Processing $file file..."
+ keytool -import -noprompt -alias $file -keystore $trust_store_path -file $file -storepass $trust_store_pass
+ rc=$?; if [[ $rc != 0 ]]; then cleanup; exit $rc; fi
+done
+
+cleanup
+
+echo "successfully generated trust store"
+
diff --git a/aws-setup/zms-setup/build/bin/initialize_zms.sh b/aws-setup/zms-setup/build/bin/initialize_zms.sh
new file mode 100755
index 00000000000..23a34db79bb
--- /dev/null
+++ b/aws-setup/zms-setup/build/bin/initialize_zms.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+Usage: initialize_zms.sh
+
+# Runs aws_zms_truststore_gen.sh to get trust store
+# Runs ws_java_truststore_gen.sh to get java trust store
+# Runs aws_zms_keystore_gen.sh to generate key store.
+
+set -e
+
+echo "creating aws config"
+/opt/zms/bin/aws_config.sh
+
+echo "initializing aws cloudwatch log setup"
+sudo python /opt/zms/logs/awslogs-agent-setup.py -n -r $REGION -c /opt/zms/conf/awslogs.conf
+
+cd /opt/zms/temp
+
+echo "generating zms trust store /opt/zms/bin/aws_zms_truststore_gen.sh $ZMS_DATA_BUCKET_NAME $ZMS_TRUST_STORE_PATH"
+rm -f $ZMS_TRUST_STORE_PATH
+/opt/zms/bin/aws_zms_truststore_gen.sh $ZMS_DATA_BUCKET_NAME $ZMS_TRUST_STORE_PATH
+
+echo "generating java trust store $JDK_CA_CERTS_PATH $JDK_CA_CERTS_PWD $ZMS_DATA_BUCKET_NAME $TRUST_STORE_PATH"
+rm -f $TRUST_STORE_PATH
+/opt/zms/bin/aws_java_truststore_gen.sh $JDK_CA_CERTS_PATH $JDK_CA_CERTS_PWD $ZMS_DATA_BUCKET_NAME $TRUST_STORE_PATH
+
+echo "generating zms key store /opt/zms/bin/aws_zms_keystore_gen.sh $ZMS_DATA_BUCKET_NAME $KEY_STORE_PATH"
+rm -f $KEY_STORE_PATH
+/opt/zms/bin/aws_zms_keystore_gen.sh $ZMS_DATA_BUCKET_NAME $KEY_STORE_PATH
+
+echo "Adding domain admin /opt/zms/bin/add_user.sh $DOMAIN_ADMIN $ZMS_DATA_BUCKET_NAME"
+/opt/zms/bin/add_user.sh $DOMAIN_ADMIN $ZMS_DATA_BUCKET_NAME
+
+
diff --git a/aws-setup/zms-setup/build/bin/zms.sh b/aws-setup/zms-setup/build/bin/zms.sh
new file mode 100755
index 00000000000..13dd1c579e5
--- /dev/null
+++ b/aws-setup/zms-setup/build/bin/zms.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+set -e
+
+source /opt/zms/bin/aws_init.sh
+
+/opt/zms/bin/initialize_zms.sh
+cd /opt/zms
+
+# setup our database cluster endpoint and other environment
+# specific settings. us-west-2 is our primary region while
+
+# us-east-1 is our backup read-only region
+
+JAVA_OPTS="-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+PrintGCDetails -Xloggc:/opt/zms/logs/gc.log"
+JAVA_OPTS="${JAVA_OPTS} -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation"
+JAVA_OPTS="${JAVA_OPTS} -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=4M"
+JAVA_OPTS="${JAVA_OPTS} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/zms/logs"
+
+java -server $JAVA_OPTS \
+ -Dathenz.root_dir=/opt/zms \
+ -Dathenz.zms.root_dir=/opt/zms \
+ -Dlogback.configurationFile=/opt/zms/conf/logback.xml \
+ -Dathenz.prop_file=/opt/zms/conf/athenz.properties \
+ -Dathenz.zms.prop_file=/opt/zms/conf/zms.properties \
+ -Dathenz.aws.zms.bucket_name=$ZMS_DATA_BUCKET_NAME \
+ -Dathenz.ssl_key_store_password_appname=$ZMS_DATA_BUCKET_NAME \
+ -Dathenz.ssl_trust_store_password_appname=$ZMS_DATA_BUCKET_NAME \
+ -Dathenz.zms.jdbc_store=jdbc:mysql://${RDS_MASTER}:3306/${DATASTORE_NAME} \
+ -Dathenz.zms.jdbc_app_name=$ZMS_DATA_BUCKET_NAME \
+ -Dathenz.zms.aws_rds_master_instance=$RDS_MASTER \
+ -Dathenz.aws.s3.region=$REGION \
+ -Dathenz.zms.read_only_mode=false \
+ -classpath ":/opt/zms/jars/*:" \
+ com.yahoo.athenz.container.AthenzJettyContainer
diff --git a/aws-setup/zms-setup/build/conf/athenz.properties b/aws-setup/zms-setup/build/conf/athenz.properties
new file mode 100755
index 00000000000..1939587d449
--- /dev/null
+++ b/aws-setup/zms-setup/build/conf/athenz.properties
@@ -0,0 +1,163 @@
+# Athenz Jetty Container properties file.
+# If there is a value specified in the commented property line,
+# then it indicates the default value
+
+# The TLS port that Jetty will listen on for HTTPS connection
+athenz.tls_port=4443
+
+# The standard HTTP port for Jetty - disabled by default
+athenz.port=0
+
+# Port for requesting /status health check. If this setting is
+# not specified, then the request will be handled by either http
+# or https ports specified in the configuration. However, if this
+# status port is specified and is different than the configured
+# http and https ports, then /status endpoint will only be handled
+# on this port and all other requests will be rejected. Similarly,
+# /status endpoint will not be allowed on configured http/https
+# ports. The status port will be either http or https depending
+# which port is specified for data access. If both http and https
+# ports are specified, https will be selected for the protocol.
+athenz.status_port=8443
+
+# Set the number of days before rotated access log files are deleted
+athenz.access_log_retain_days=31
+
+# Format of the access log filename
+athenz.access_log_name=access.yyyy_MM_dd.log
+
+# If specified, the server will use SLF4J logger with the specified name
+# to log events instead of using Jetty's NCSARequestLog class.
+# The administrator then must configure the specified logger in the logback.xml
+athenz.access_slf4j_logger=
+
+# Directory to store access log files
+athenz.access_log_dir=/opt/zms/logs
+
+# Key Manager password
+#athenz.ssl_key_manager_password=
+
+# The path to the keystore file that contains the server's certificate
+athenz.ssl_key_store=/opt/zms/conf/zms_keystore.pkcs12
+
+# Specifies the type for the keystore specified in the
+# athenz.ssl_key_store property
+athenz.ssl_key_store_type=PKCS12
+
+# Password for the keystore specified in the athenz.ssl_key_store property
+athenz.ssl_key_store_password=service_x509_store_pwd
+
+# The path to the trust store file that contains CA certificates
+# trusted by this Jetty instance
+athenz.ssl_trust_store=/opt/zms/conf/zms_truststore.jks
+
+# Specifies the type for the truststore specified in the
+# athenz.ssl_trust_store property
+athenz.ssl_trust_store_type=JKS
+
+# Password for the truststore specified in the athenz.ssl_trust_store property
+athenz.ssl_trust_store_password=service_x509_store_pwd
+
+# Specifies whether or not for data requests the server
+# would require TLS client authentication rather than
+# just wanting it
+athenz.ssl_need_client_auth=false
+
+# Configure if client TLS renegotiation is allowed or not
+athenz.ssl_renegotiation_allowed=false
+
+# Enable OCSP support
+#athenz.ssl_enable_ocsp=false
+
+# Private key store to extract the passwords defined for
+# java keystore and truststore
+athenz.private_keystore_factory_class=com.yahoo.athenz.auth.impl.aws.AwsPrivateKeyStoreFactory
+
+# Specifies the truststore used by java clients when communicating
+# with other AWS services like S3 or RDS. This should be the
+# JDK shipped truststore + AWS RDS CA truststore
+javax.net.ssl.trustStore=/opt/zms/conf/zms_java_truststore.jks
+javax.net.ssl.trustStorePassword=changeit
+
+# List of excluded cipher suites from TLS negotiation
+#athenz.ssl_excluded_cipher_suites=
+
+# List of cipher suites supported for TLS negotiation
+athenz.ssl_included_cipher_suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA
+
+#Comma separated list of excluded ssl protocols
+#athenz.ssl_excluded_protocols=SSLv2,SSLv3
+
+# In milliseconds how long that connector will be allowed to
+# remain idle with no traffic before it is shutdown
+athenz.http_idle_timeout=30000
+
+# Boolean setting to specify whether or not the server should
+# send the Server header in response
+athenz.http_send_server_version=false
+
+# Boolean setting to specify whether or not the server should
+# include the Date in HTTP headers
+athenz.http_send_date_header=false
+
+# The size in bytes of the output buffer used to aggregate HTTP output
+#athenz.http_output_buffer_size=32768
+
+# The maximum allowed size in bytes for a HTTP request header
+#athenz.http_reqeust_header_size=8192
+
+# The maximum allowed size in bytes for a HTTP response header
+#athenz.http_response_header_size=8192
+
+# For HTTP access specifies the IP address/Host for service to listen on.
+# This could be necessary, for example, if the system administrator
+# wants some proxy server (e.g. ATS) to handle TLS traffic and configure
+# Jetty to listen on 127.0.0.1 loopback address only for HTTP connections
+# from that proxy server
+#athenz.listen_host=
+
+# Boolean flag to indicate whether or not the container should honor
+# the Keep Alive connection option or just connections right away
+#athenz.keep_alive=false
+
+# Max number of threads Jetty is allowed to spawn to handle incoming requests
+athenz.http_max_threads=1024
+
+# Specify the FQDN/hostname of the server. This will be reported as part
+# of the server banner notification in logs
+#athenz.hostname=
+
+# Default home directory for embedded Jetty Deployer. The container will look
+# for any servlets in the webapps subdirectory of the configured directory
+athenz.jetty_home=/opt/zms
+
+# Boolean flag to enable debug log entries when deploying webapps
+#athenz.debug=false
+
+# Comma separated liste of uris that are accessed by health check
+# system. Used by the simple file based health check filter that
+# returns 200/404 if the file exists or not
+athenz.health_check_uri_list=/status
+
+# Directory name where the files specified in the athenz.health_check_uri_list
+# setting are checked for
+athenz.health_check_path=/opt/zms
+
+# Enable Proxy Protocol (used by HAProxy and environments such as Amazon Elastic Cloud)
+# for the jetty container.
+athenz.proxy_protocol=true
+
+# Enable rate limit
+athens.server_common.ratelimit.enable_ratelimit=true
+
+# Ratelimit factory class name
+athenz.ratelimit_factory_class=com.yahoo.athenz.common.filter.impl.NoOpRateLimitFactory
+
+# Ratelimit whitelisted role names comma delimited
+#athens.server_common.ratelimit.whitelist_roles=
+
+# Ratelimit limit
+athens.server_common.ratelimit.limit_count=100
+
+# Ratelimit limit per resource
+athens.server_common.ratelimit.rules=/access/:25,/sys/:3
diff --git a/aws-setup/zms-setup/build/conf/awslogs.conf b/aws-setup/zms-setup/build/conf/awslogs.conf
new file mode 100755
index 00000000000..73e10c8b1a6
--- /dev/null
+++ b/aws-setup/zms-setup/build/conf/awslogs.conf
@@ -0,0 +1,26 @@
+[general]
+state_file = /var/awslogs/state/agent-state
+
+[syslog]
+file = /var/log/messages
+log_group_name = athenz-zms-service-syslog
+log_stream_name = {instance_id}
+datetime_format = %b %d %H:%M:%S
+
+[access]
+file = /opt/zms/logs/access*.log
+log_group_name = athenz-zms-service-access
+log_stream_name = {instance_id}
+datetime_format = %b %d %H:%M:%S
+
+[server]
+file = /opt/zms/logs/zms_server/server*.log
+log_group_name = athenz-zms-service-server
+log_stream_name = {instance_id}
+datetime_format = %b %d %H:%M:%S
+
+[gc]
+file = /opt/zms/logs/gc.log.*
+log_group_name = athenz-zms-service-gc
+log_stream_name = {instance_id}
+datetime_format = %b %d %H:%M:%S
\ No newline at end of file
diff --git a/aws-setup/zms-setup/build/conf/logback.xml b/aws-setup/zms-setup/build/conf/logback.xml
new file mode 100755
index 00000000000..e714e369e58
--- /dev/null
+++ b/aws-setup/zms-setup/build/conf/logback.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+ ${LOG_DIR}/server.log
+ true
+
+
+ ${LOG_DIR}/server.%d.log
+ 7
+ true
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n
+
+
+
+
+
+
+ ${LOG_DIR}/audit.log
+ true
+
+
+ ${LOG_DIR}/audit.%d.log
+ 30
+ true
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/aws-setup/zms-setup/build/conf/zms-user b/aws-setup/zms-setup/build/conf/zms-user
new file mode 100755
index 00000000000..40eccf6448f
--- /dev/null
+++ b/aws-setup/zms-setup/build/conf/zms-user
@@ -0,0 +1 @@
+athenz-zms ALL=(ALL) NOPASSWD: ALL
\ No newline at end of file
diff --git a/aws-setup/zms-setup/build/conf/zms.properties b/aws-setup/zms-setup/build/conf/zms.properties
new file mode 100755
index 00000000000..ba7fa6a9e12
--- /dev/null
+++ b/aws-setup/zms-setup/build/conf/zms.properties
@@ -0,0 +1,352 @@
+# Athenz ZMS Servlet properties file.
+# If there is a value specified in the commented property line,
+# then it indicates the default value
+
+# Comma separated list of authority implementation classes to support
+# authenticating principals in ZMS
+athenz.zms.authority_classes=com.yahoo.athenz.auth.impl.PrincipalAuthority,com.yahoo.athenz.auth.impl.UserAuthority
+
+# Principal Authority class. If defined and the caller asks for the header
+# name for the getUserToken api, the header from this authority will be
+# returned in the response. This class must be one of the classes listed
+# in the athenz.zms.authority_classes setting
+#athenz.zms.principal_authority_class=
+
+# Specifies the user domain name for the current installation
+#athenz.user_domain=user
+#athens.auth_core.bouncer.domain=user
+
+# Specifies the user domain alias name for the current installation
+#athenz.user_domain_alias=yby
+
+# Specifies the personal home domain name for the current installation
+athenz.home_domain=home
+
+# Specifies the factory class that implements the Metrics interface
+# used by the ZMS Server to report stats
+athenz.zms.metric_factory_class=com.yahoo.athenz.common.metrics.impl.NoOpMetricFactory
+
+# Specifies the factory class that implements the AuditLoggerFactory
+# interface used by the ZMS Server to log all changes to domain
+# data for auditing purposes
+athenz.zms.audit_logger_factory_class=com.yahoo.athenz.common.server.log.impl.DefaultAuditLoggerFactory
+
+# Specifies the factory class that implements the PrivateKeyStoreFactory
+# interface used by the ZMS Server to get access to its host specific
+# private key
+athenz.zms.private_key_store_factory_class=com.yahoo.athenz.auth.impl.aws.AwsPrivateKeyStoreFactory
+
+# If the datastore does not contain any domains during startup,
+# the server will automatically create sys, sys.auth and user
+# domains and assign the specified users (comma separated list)
+# as the administrator for those domains
+athenz.zms.domain_admin=user.zms-admin
+
+# If File Private Key store implementation is used in the Server,
+# this setting specifies the path to the PEM encoded ZMS Server
+# private key file (both RSA and EC privates keys are supported)
+#athenz.auth.private_key_store.private_key=/opt/zms/var/zms_server/keys/zms_private.pem
+
+# If File Private Key store implementation is used in the Server,
+# this setting specifies the key identifier for the private key
+# configured by the athenz.auth.private_key_store.private_key
+# property
+#athenz.auth.private_key_store.private_key_id=0
+
+# Specify the FQDN/hostname of the server. This value will be used as the
+# h parameter in the ZMS generated UserTokens
+#athenz.zms.hostname=
+
+# Specifies the authorized service json configuration file path.
+#athenz.zms.authz_service_fname=
+
+# Specifies the path to the solution templates json document
+#athenz.zms.solution_templates_fname=
+
+# In case there is a concurrent update conflict, the server will retry
+# the operation multiple times until this timeout is reached before
+# returning a conflict status code back to the client
+#athenz.zms.conflict_retry_timeout=60
+
+# When ZMS determines that updating a domain data tables will cause a
+# concurrent update issue and needs to retry the operation, it will sleep
+# configured number of milliseconds before retrying
+#athenz.zms.retry_delay_timeout=50
+
+# This setting specifies the number of seconds how long the signed
+# policy documents are valid for
+#athenz.zms.signed_policy_timeout=604800
+
+# The number of milliseconds to sleep between runs of the idle object
+# evictor thread. When non-positive, no idle object evictor thread
+# will be run. The pool default is -1, but we're using 30 minutes to
+# make sure the evictor thread is running |
+#athenz.db.pool_evict_idle_interval=1800000
+
+# The minimum amount of time (in milliseconds) an object may sit
+# idle in the pool before it is eligible for eviction by the idle
+# object evictor (if any)
+#athenz.db.pool_evict_idle_timeout=1800000
+
+# The maximum number of connections that can remain idle in the pool,
+# without extra ones being released, or negative for no limit
+#athenz.db.pool_max_idle=8
+
+# The maximum number of active connections that can be allocated
+# from this pool at the same time, or negative for no limit
+#athenz.db.pool_max_total=8
+
+# The maximum lifetime in milliseconds of a connection. After this
+# time is exceeded the connection will fail the next activation,
+# passivation or validation test. A value of zero or less means the
+# connection has an infinite lifetime
+#athenz.db.pool_max_ttl=600000
+
+# The maximum number of milliseconds that the pool will wait
+# (when there are no available connections) for a connection to be
+# returned before throwing an exception, or -1 to wait indefinitely
+#athenz.db.pool_max_wait=-1
+
+# The minimum number of connections that can remain idle in the pool,
+# without extra ones being created, or zero to create none
+#athenz.db.pool_min_idle=0
+
+# The maximum number of seconds that the server should wait
+# for the store connection object to return its results
+#athenz.zms.store_operation_timeout=60
+
+# Specifies the factory class that implements the ObjectStoreFactory
+# interface used by the ZMS Server to store its data. In production,
+# this is typically the jdbc/mysql object store while for tests it's
+# the file object store
+athenz.zms.object_store_factory_class=com.yahoo.athenz.zms.store.impl.JDBCObjectStoreFactory
+
+# If the athenz.zms.object_store_factory_class property is using
+# the file object store factory, then this setting specifies
+# the subdirectory name where domain files will be stored.
+# The parent directory is identified by the athenz.zms.file_store_path
+# property
+#athenz.zms.file_store_path=/opt/zms/var/zms_server
+
+# If the athenz.zms.object_store_factory_class property is using
+# the file object store factory, then this setting specifies
+# the directory name where file store subdirectory will
+# be created to store domain files. The subdirectory is identified
+# by the athenz.zms.file_store_name property
+#athenz.zms.file_store_name=zms_root
+
+# If the athenz.zms.object_store_factory_class property is using
+# the jdbc object store factory identified with
+# com.yahoo.athenz.zms.store.impl.JDBCObjectStoreFactory, then
+# this setting specifies JDBC URL where the ZMS Server will store its data.
+# The database server must be initialized with the ZMS
+# server schema. For example, jdbc:mysql://localhost:3306/zms
+# specifies a database called zms configured within a
+# MySQL instance
+#athenz.zms.jdbc_store=
+
+# If the athenz.zms.object_store_factory_class property is using
+# the jdbc/mysql object store factory then this setting
+# specifies the name of the user that has full access to the configured
+# ZMS server database
+athenz.zms.jdbc_user=athenz-zms
+
+# If the athenz.zms.object_store_factory_class property is using
+# the jdbc/mysql object store factory then this setting
+# specifies the password key for the jdbc user that has been granted full
+# access to the configured ZMS server database. The configured
+# private key store will be called with the value of the key to
+# retrieve the password to authenticate requests against the
+# configured MySQL server.
+athenz.zms.jdbc_password=db_user_data
+
+# If the athenz.zms.object_store_factory_class property is using
+# the jdbc/mysql object store factory then this setting specifies
+# JDBC URL for slave databases that replicate ZMS Server's
+# domain data. If configured, ZMS Server will use this database
+# instance for any read only operation. It has the same syntax
+# as the athenz.zms.jdbc_store property.
+#athenz.zms.jdbc_ro_store=
+
+# If the athenz.zms.jdbc_ro_store is configured then this property is
+# the name of the user that has full access to the zms database
+# if this property is not specified but athenz.zms.jdbc_ro_store
+# is configured, the server will use the value of the
+# athenz.zms.jdbc_user property.
+#athenz.zms.jdbc_ro_user=
+
+# If the athenz.zms.jdbc_ro_store is configured then this property
+# specifies the password key for the jdbc user that has been granted
+# full access to the configured zms database. If this property is not
+# specified but athenz.zms.jdbc_ro_store is configured, the server
+# will use the value of the athenz.zms.jdbc_password property.
+# The configured private key store will be called with the value of
+# the key to retrieve the password to authenticate requests against
+# the configured MySQL server.
+#athenz.zms.jdbc_ro_password=
+
+# If using the jdbc connector (either mysql or aws) for zms
+# data storage, this property specifies if the jdbc client
+# should establish an SSL connection to the database server or not
+athenz.zms.jdbc_use_ssl=false
+
+# if using the jdbc connector (either mysql or aws) for zms
+# data storage and the athenz.zms.jdbc_use_ssl property is set
+# to true, this property specifies whether or not the jdbc client
+# must verify the server certificate or not
+athenz.zms.jdbc_verify_server_certificate=true
+
+# If the athenz.zms.object_store_factory_class property is using
+# the aws rds mysql object store factory identified with
+# com.yahoo.athenz.zms.store.impl.AWSObjectStoreFactory, then
+# this setting specifies AWS RDS instance hostname.
+# The database server must be initialized with the ZMS
+# server schema.
+#athenz.zms.aws_rds_master_instance=
+
+# If the athenz.zms.object_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# the database user configured with IAM Role AWS authentication
+# and full access to the zms store database
+athenz.zms.aws_rds_user=zms
+
+# If the athenz.zms.object_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# the IAM role that has been enabled for authentication
+athenz.zms.aws_rds_iam_role=athenz.zms-service
+
+# If the athenz.zms.object_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# the port number for the RDL database instance
+athenz.zms.aws_rds_master_port=3306
+
+# If the athenz.zms.object_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# the database engine used in rds
+athenz.zms.aws_rds_engine=mysql
+
+# If the athenz.zms.object_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# the database name in rds
+athenz.zms.aws_rds_database=zmsstore
+
+# If the athenz.zms.object_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# in seconds how often to update the aws credentials for the IAM role
+athenz.zms.aws_rds_creds_refresh_time=300
+
+# The number of seconds ZMS issued User Tokens are valid for
+#athenz.zms.user_token_timeout=3600
+
+# Boolean setting to configure whether or not virtual domains are
+# supported or not. These are domains created in the user's own
+# "user" namespace
+#athenz.zms.virtual_domain_support=true
+
+# If virtual domain support is enabled, this setting specifies the
+# number of sub domains in the user's virtual namespace that are
+# allowed to be created. Value of 0 indicates no limit
+#athenz.zms.virtual_domain_limit=5
+
+# Number of bytes allowed to be specified in a domain name.
+# This limit includes all subdomains as well. For example,
+# athenz.storage.mysql domains length is 20.
+#athenz.zms.domain_name_max_len=128
+
+# Boolean setting to configure whether or not unique product
+# IDs are required for top level domains
+athenz.zms.product_id_support=false
+
+# Number of seconds the authentication library will honor
+# token's expiration timeout.
+#athenz.token_max_expiry=2592000
+
+# For read operations allow tokens with no expiry
+athenz.token_no_expiry=true
+
+# User Authority - if UserAuthority is enabled as one of the authenticating
+# authorities in the ZMS Server, this setting provides the pam service
+# name used when validating the user specified password
+#athenz.auth.user.pam_service_name=login
+
+# Role Authority - when validating Role Tokens, this setting specifies the
+# number seconds the library will allow the token to have a creation time
+# in the future to accommodate time differences between server and client.
+#athenz.auth.role.token_allowed_offset=300
+
+# Role Authority - when authenticating principals based on the Role Token
+# this setting specifies what HTTP header name in the request contains
+# the token
+#athenz.auth.role.header=Athenz-Role-Auth
+
+# Principal Authority - when validating User/Service Tokens, this setting
+# specifies the number seconds the library will allow the token to have
+# a creation time in the future to accommodate time differences between
+# server and client.
+#athenz.auth.principal.token_allowed_offset=300
+
+# Principal Authority - when authenticating principals based on their
+# User/Service Tokens, this setting specifies what HTTP header name in
+# the request contains the token
+#athenz.auth.principal.header=Athenz-Principal-Auth
+
+# Principal Authority - when authenticating principals based on their
+# User/Service Tokens. this setting specifies whether or not to validate
+# if the IP address of the incoming connection matches to the IP address
+# in the token. The possible values are: OPS_ALL, OPS_NONE, OPS_WRITE
+# OPS_WRITE indicates that only write/update operation will enforce
+# this check.
+#athenz.auth.principal.remote_ip_check_mode=OPS_WRITE
+
+# If the ZMS webapp is deployed along other webapps that may
+# run on non-TLS ports, this setting forces that requests to
+# ZMS are only accepted on secure TLS ports.
+#athenz.zms.secure_requests_only=true
+
+# Quota Support: boolean value defining whether or not quota
+# check is enabled.
+athenz.zms.quota_check=true
+
+# Quota Support: default number of roles allowed to be created
+# in a given domain.
+athenz.zms.quota_role=1000
+
+# Quota Support: default number of members a single role may have
+athenz.zms.quota_role_member=500
+
+# Quota Support: default number of polices allowed to be created
+# in a given domain.
+athenz.zms.quota_policy=1000
+
+# Quota Support: default number of assertions each policy may have
+athenz.zms.quota_assertion=500
+
+# Quota Support: default number of services allowed to be created
+# in a given domain.
+athenz.zms.quota_service=250
+
+# Quota Support: default number of hosts each service may have
+athenz.zms.quota_service_host=100
+
+# Quota Support: default number of public keys each service may have
+athenz.zms.quota_public_key=100
+
+# Quota Support: default number of entities allowed to be created
+# in a given domain
+athenz.zms.quota_entity=100
+
+# Quota Support: default number of sub-domains each top level
+# domain allowed to have.
+athenz.zms.quota_subdomain=100
+
+# Comma separated list of URIs that require authentication according to the RDL
+# but we want the server to make the authentication as optional. The URI can
+# include regex values based on + character to match resource URIs
+# for example, /zms/v1/domain/.+/service
+athenz.zms.no_auth_uri_list=/zms/v1/status
+
+# Comma separated list of principals to be excluded from
+# certificate authority validation. This would include
+# Athenz UI and Proxy services
+athenz.auth.certificate.excluded_principals=
+
diff --git a/aws-setup/zms-setup/build/service/zms.service b/aws-setup/zms-setup/build/service/zms.service
new file mode 100755
index 00000000000..7e2d27af6c5
--- /dev/null
+++ b/aws-setup/zms-setup/build/service/zms.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Athenz ZMS Service
+Wants=network-online.target ntpd.service
+After=network-online.target
+
+[Service]
+ExecStart=/opt/zms/bin/zms.sh
+Restart=on-failure
+RestartSec=20
+
+[Install]
+WantedBy=multi-user.target
diff --git a/aws-setup/zms-setup/cloud-formation/athens-zms-aws-resource-setup.yaml b/aws-setup/zms-setup/cloud-formation/athens-zms-aws-resource-setup.yaml
new file mode 100755
index 00000000000..bdf9546c521
--- /dev/null
+++ b/aws-setup/zms-setup/cloud-formation/athens-zms-aws-resource-setup.yaml
@@ -0,0 +1,609 @@
+AWSTemplateFormatVersion: 2010-09-09
+Description: 'Athenz ZMS standard 2 Availabilty zone configuration template'
+Parameters:
+ ZMSServiceName:
+ Type: String
+ Description: The service name for ZMS server
+ Default: "zms"
+ ZMSVPCCidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the ZMS VPC.
+ Default: "10.0.0.0/20"
+ PrivateSubnet01CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Private Subnet Zone 1.
+ Default: "10.0.0.0/22"
+ PrivateSubnet02CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Private Subnet Zone 2.
+ Default: "10.0.4.0/22"
+ PublicSubnet01CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Public Subnet Zone 1.
+ Default: "10.0.8.0/22"
+ PublicSubnet02CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Public Subnet Zone 2.
+ Default: "10.0.12.0/22"
+ GroupName:
+ Type: String
+ Description: The Athens domain for the account
+ Default: "Athenz"
+ Environment:
+ Type: String
+ Description: The environment ZMS is running in
+ AllowedValues:
+ - prod
+ - stage
+ - dev
+ S3AccessLogBucketName:
+ Type: String
+ Description: S3 bucket name to store access logs
+ Route53HostedZoneName:
+ Type: String
+ Description: The hosted zone name to place a CNAME entry for. Must end with a period. Empty string means do not create one.
+ Route53RecordName:
+ Type: String
+ Description: The hosted records to be added
+Conditions:
+ CreateDNSRecordSet: !Not [!Equals [ !Ref Route53HostedZoneName, '']]
+
+
+Resources:
+ ZMSVPC:
+ Type: 'AWS::EC2::VPC'
+ Properties:
+ CidrBlock: !Ref 'ZMSVPCCidrBlock'
+ EnableDnsSupport: true
+ EnableDnsHostnames: true
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet01:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PrivateSubnet01CidrBlock'
+ VpcId: !Ref 'ZMSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}-${AWS::Region}a-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet02:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 1
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PrivateSubnet02CidrBlock'
+ VpcId: !Ref 'ZMSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}-${AWS::Region}b-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet01:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PublicSubnet01CidrBlock'
+ VpcId: !Ref 'ZMSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}-${AWS::Region}a-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet02:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 1
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PublicSubnet02CidrBlock'
+ VpcId: !Ref 'ZMSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}-${AWS::Region}b-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ Nacl:
+ Type: "AWS::EC2::NetworkAcl"
+ Properties:
+ VpcId: !Ref 'ZMSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ NetworkAclEntry01:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '100'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: !Ref 'ZMSVPCCidrBlock'
+ PortRange:
+ From: '22'
+ To: '22'
+ NetworkAclEntry02:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '110'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '4443'
+ To: '4443'
+ NetworkAclEntry03:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '120'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '8443'
+ To: '8443'
+ NetworkAclEntry04:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '130'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '3306'
+ To: '3306'
+ NetworkAclEntry05:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '140'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '80'
+ To: '80'
+ NetworkAclEntry06:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '150'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '443'
+ To: '443'
+ NetworkAclEntry07:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '160'
+ Protocol: "17"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '123'
+ To: '123'
+ NetworkAclEntry08:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '200'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '1024'
+ To: '65535'
+ NetworkAclEntry09:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '100'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '22'
+ To: '22'
+ NetworkAclEntry10:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '110'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '4443'
+ To: '4443'
+ NetworkAclEntry11:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '120'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '8443'
+ To: '8443'
+ NetworkAclEntry12:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '130'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '3306'
+ To: '3306'
+ NetworkAclEntry13:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '140'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '80'
+ To: '80'
+ NetworkAclEntry14:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '160'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '443'
+ To: '443'
+ NetworkAclEntry15:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '150'
+ Protocol: "17"
+ RuleAction: allow
+ CidrBlock: !Ref 'ZMSVPCCidrBlock'
+ PortRange:
+ From: '123'
+ To: '123'
+ NetworkAclEntry16:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '200'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '1024'
+ To: '65535'
+ PrivateSubnet01Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PrivateSubnet01'
+ NetworkAclId: !Ref 'Nacl'
+ PrivateSubnet02Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PrivateSubnet02'
+ NetworkAclId: !Ref 'Nacl'
+ PublicSubnet01Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PublicSubnet01'
+ NetworkAclId: !Ref 'Nacl'
+ PublicSubnet02Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PublicSubnet02'
+ NetworkAclId: !Ref 'Nacl'
+ InternetGateway:
+ Type: "AWS::EC2::InternetGateway"
+ Properties:
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ VPCGatewayAttachment:
+ Type: "AWS::EC2::VPCGatewayAttachment"
+ Properties:
+ InternetGatewayId: !Ref 'InternetGateway'
+ VpcId: !Ref 'ZMSVPC'
+ PublicSubnet01NatGateway:
+ Type: "AWS::EC2::NatGateway"
+ Properties:
+ AllocationId: !GetAtt PublicSubnet01EIP.AllocationId
+ SubnetId: !Ref 'PublicSubnet01'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}-${AWS::Region}a
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet01EIP:
+ DependsOn: VPCGatewayAttachment
+ Type: AWS::EC2::EIP
+ Properties:
+ Domain: vpc
+ PublicSubnet02NatGateway:
+ Type: "AWS::EC2::NatGateway"
+ Properties:
+ AllocationId: !GetAtt PublicSubnet02EIP.AllocationId
+ SubnetId: !Ref 'PublicSubnet02'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}-${AWS::Region}b
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet02EIP:
+ DependsOn: VPCGatewayAttachment
+ Type: AWS::EC2::EIP
+ Properties:
+ Domain: vpc
+ PublicSubnetRouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'ZMSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}-${AWS::Region}-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ GatewayRoute:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ GatewayId: !Ref 'InternetGateway'
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ DependsOn: VPCGatewayAttachment
+ PrivateSubnet01RouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'ZMSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}-${AWS::Region}a-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet01Route:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ NatGatewayId: !Ref 'PublicSubnet01NatGateway'
+ RouteTableId: !Ref 'PrivateSubnet01RouteTable'
+ PrivateSubnet02RouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'ZMSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZMSServiceName}-${AWS::Region}b-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet02Route:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ NatGatewayId: !Ref 'PublicSubnet02NatGateway'
+ RouteTableId: !Ref 'PrivateSubnet02RouteTable'
+ DependsOn: VPCGatewayAttachment
+ PublicSubnet01RouteTableAssociaton:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ SubnetId: !Ref 'PublicSubnet01'
+ PublicSubnet02RouteTableAssociaton:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ SubnetId: !Ref 'PublicSubnet02'
+ PrivateSubnet01RouteTableAssociation:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PrivateSubnet01RouteTable'
+ SubnetId: !Ref 'PrivateSubnet01'
+ PrivateSubnet02RouteTableAssociation:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PrivateSubnet02RouteTable'
+ SubnetId: !Ref 'PrivateSubnet02'
+ ZMSELBSecurityGroup:
+ Type: "AWS::EC2::SecurityGroup"
+ Properties:
+ GroupName: !Sub ${GroupName}-${Environment}-elb-sg-${ZMSServiceName}-${AWS::Region}
+ GroupDescription: 'ZMS public elb security group'
+ SecurityGroupIngress:
+ - IpProtocol: tcp
+ FromPort: '4443'
+ ToPort: '4443'
+ CidrIp: '0.0.0.0/0'
+ VpcId: !Ref 'ZMSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-elb-${ZMSServiceName}-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ ZMSServerSecurityGroup:
+ Type: "AWS::EC2::SecurityGroup"
+ Properties:
+ GroupName: !Sub ${GroupName}-${Environment}-server-sg-${ZMSServiceName}-${AWS::Region}
+ GroupDescription: 'ZMS public server security group'
+ SecurityGroupIngress:
+ - IpProtocol: tcp
+ FromPort: '4443'
+ ToPort: '4443'
+ CidrIp: '0.0.0.0/0'
+ - IpProtocol: tcp
+ FromPort: '8443'
+ ToPort: '8443'
+ CidrIp: !Ref 'ZMSVPCCidrBlock'
+ VpcId: !Ref 'ZMSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-server-${ZMSServiceName}-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ ZMSLoadBalancer:
+ Type: "AWS::ElasticLoadBalancing::LoadBalancer"
+ Properties:
+ HealthCheck:
+ HealthyThreshold: 2
+ Interval: 5
+ Target: !Sub HTTPS:8443/${ZMSServiceName}/v1/status
+ Timeout: 3
+ UnhealthyThreshold: 4
+ Listeners:
+ - InstancePort: 4443
+ InstanceProtocol: TCP
+ LoadBalancerPort: 4443
+ Protocol: TCP
+ Policies:
+ - PolicyName: "EnableProxyProtocol"
+ PolicyType: "ProxyProtocolPolicyType"
+ Attributes:
+ - Name: ProxyProtocol
+ Value: 'true'
+ InstancePorts:
+ - '4443'
+ LoadBalancerName: !Sub ${Environment}-elb-${ZMSServiceName}-${AWS::Region}
+ Scheme: 'internet-facing'
+ ConnectionDrainingPolicy:
+ Enabled: 'true'
+ Timeout: '60'
+ CrossZone: true
+ SecurityGroups:
+ - !Ref ZMSELBSecurityGroup
+ Subnets:
+ - !Ref 'PublicSubnet01'
+ - !Ref 'PublicSubnet02'
+ AccessLoggingPolicy:
+ S3BucketName: !Ref S3AccessLogBucketName
+ S3BucketPrefix: !Sub elb-${ZMSServiceName}
+ Enabled: 'true'
+ EmitInterval: '5'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-elb-ZMS-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ ZMSRecordSet:
+ Type: AWS::Route53::RecordSet
+ Condition: CreateDNSRecordSet
+ Properties:
+ Comment: CNAME record for the ZMS Server.
+ HostedZoneName: !Ref Route53HostedZoneName
+ Name: !Ref Route53RecordName
+ TTL: 60
+ Type: CNAME
+ ResourceRecords:
+ - !GetAtt ZMSLoadBalancer.DNSName
+Outputs:
+ ZMSVPCID:
+ Description: The ID of the ZMS VPC
+ Value: !Ref ZMSVPC
+ Export:
+ Name: !Sub "${AWS::StackName}-VPCID"
+ PrivateSubnet01ID:
+ Description: TThe ID of Private Subnet Availability Zone 1 in ZMS VPC
+ Value: !Ref PrivateSubnet01
+ Export:
+ Name: !Sub "${AWS::StackName}-PrivateSubnet01ID"
+ PrivateSubnet02ID:
+ Description: The ID of Private Subnet Availability Zone 2 in ZMS VPC
+ Value: !Ref PrivateSubnet02
+ Export:
+ Name: !Sub "${AWS::StackName}-PrivateSubnet02ID"
+ LoadBalancerName :
+ Description: The name of ZMS Load Balancer
+ Value: !Ref ZMSLoadBalancer
+ Export:
+ Name: !Sub "${AWS::StackName}-LoadBalancerName"
+ ServerSecurityGroupID:
+ Description: TThe ID of ZMS Server security group
+ Value: !Ref ZMSServerSecurityGroup
+ Export:
+ Name: !Sub "${AWS::StackName}-ServerSecurityGroupID"
+
diff --git a/aws-setup/zms-setup/cloud-formation/athens-zms-aws-roles-setup.yaml b/aws-setup/zms-setup/cloud-formation/athens-zms-aws-roles-setup.yaml
new file mode 100755
index 00000000000..8e74080f27e
--- /dev/null
+++ b/aws-setup/zms-setup/cloud-formation/athens-zms-aws-roles-setup.yaml
@@ -0,0 +1,52 @@
+AWSTemplateFormatVersion: 2010-09-09
+Description: Roles needed for athens ZMS setup
+Parameters:
+ AthensServiceRole:
+ Type: String
+ Description: The Athens role name for the service
+ Default: athenz.zms-service
+Resources:
+ AthensServiceEC2Role:
+ Type: "AWS::IAM::Role"
+ Properties:
+ AssumeRolePolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ -
+ Effect: "Allow"
+ Principal:
+ Service:
+ - "ec2.amazonaws.com"
+ Action:
+ - "sts:AssumeRole"
+ Policies:
+ -
+ PolicyName: !Sub ${AthensServiceRole}.policy
+ PolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ - Effect: "Allow"
+ Action:
+ - logs:CreateLogGroup
+ - logs:CreateLogStream
+ - logs:PutLogEvents
+ - logs:DescribeLogStreams
+ - logs:DescribeLogGroups
+ Resource: "arn:aws:logs:*:*:*"
+ - Effect: "Allow"
+ Action:
+ - rds-db:connect
+ Resource:
+ - !Sub arn:aws:rds-db:us-west-2:${AWS::AccountId}:dbuser:*/zms
+ - !Sub arn:aws:rds-db:us-east-1:${AWS::AccountId}:dbuser:*/zms
+ - Effect: "Allow"
+ Action: "ec2:DescribeTags"
+ Resource: "*"
+ Path: /
+ RoleName: !Ref AthensServiceRole
+ AthensEc2InstanceProfile:
+ Type: "AWS::IAM::InstanceProfile"
+ Properties:
+ Roles:
+ - !Ref AthensServiceEC2Role
+ InstanceProfileName: !Ref AthensServiceRole
\ No newline at end of file
diff --git a/aws-setup/zms-setup/cloud-formation/athenz-zms-aws-instance-deployment.yaml b/aws-setup/zms-setup/cloud-formation/athenz-zms-aws-instance-deployment.yaml
new file mode 100755
index 00000000000..b27f167087a
--- /dev/null
+++ b/aws-setup/zms-setup/cloud-formation/athenz-zms-aws-instance-deployment.yaml
@@ -0,0 +1,178 @@
+Description: 'Athenz ZMS standard 2 Availabilty zone instance deployment template'
+Parameters:
+ ServiceRole:
+ Type: String
+ Description: The ZMS Service IAM Role Name
+ Default: "athenz.zms-service"
+ KeyName:
+ Type: String
+ Description: The EC2 key pair for the instance
+ ServiceName:
+ Type: String
+ Description: The service name for ZMS server
+ Default: "zms"
+ ResourceStackName:
+ Type: String
+ Description: Name of Stack used to create AWS Resources
+ Environment:
+ Type: String
+ Description: The environment ZMS is running in
+ AllowedValues:
+ - prod
+ - stage
+ - dev
+ ImageId:
+ Type: AWS::EC2::Image::Id
+ Description: "The ImageId to use for the EC2 instance. Should be a format like ami-XXXXXXXX"
+ AutoScalingMinSize:
+ Type: String
+ Description: The minimum instances for auto scaling
+ Default: "2"
+ AutoScalingMaxSize:
+ Type: String
+ Description: The maximum instances for auto scaling
+ Default: "4"
+ AutoScalingDesiredCapacity:
+ Type: String
+ Description: The desired number of instances
+ Default: "2"
+ EbsOptimized:
+ Type: String
+ Description: If EBS is to be optimized
+ AllowedValues:
+ - "true"
+ - "false"
+ Default: "false"
+ Ec2InstanceType:
+ Type: String
+ Description: The instance type to use for the host
+ Default: t2.large
+ AllowedValues:
+ - t2.nano
+ - t2.micro
+ - t2.small
+ - t2.medium
+ - t2.large
+ - t2.xlarge
+ - t2.2xlarge
+ - m4.large
+ - m4.xlarge
+ - m4.2xlarge
+ - m4.4xlarge
+ - m4.10xlarge
+ - m4.16xlarge
+ - m5.large
+ - m5.xlarge
+ - m5.2xlarge
+ - m5.4xlarge
+ - m5.12xlarge
+ - m5.24xlarge
+ - m5d.large
+ - m5d.xlarge
+ - m5d.2xlarge
+ - m5d.4xlarge
+ - m5d.12xlarge
+ - m5d.24xlarge
+ EbsVolumeType:
+ Type: String
+ Description: The value for EBS Volume type in Block Device Mappings for Launch Configuration
+ Default: "gp2"
+ EbsVolumeSize:
+ Type: Number
+ Description: The value for EBS Volume size Block Device Mappings for Launch Configuration
+ Default: "50"
+Resources:
+ ZMSEC2AutoScalingGroup:
+ Type: 'AWS::AutoScaling::AutoScalingGroup'
+ Properties:
+ LaunchConfigurationName: !Ref ZMSLaunchConfig
+ LoadBalancerNames:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-LoadBalancerName"
+ MaxSize: !Ref AutoScalingMaxSize
+ MinSize: !Ref AutoScalingMinSize
+ Cooldown: 300
+ VPCZoneIdentifier:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-PrivateSubnet01ID"
+ - Fn::ImportValue: !Sub "${ResourceStackName}-PrivateSubnet02ID"
+ DesiredCapacity: !Ref AutoScalingDesiredCapacity
+ HealthCheckGracePeriod: 900
+ HealthCheckType: ELB
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-asg-${ServiceName}-${AWS::Region}
+ PropagateAtLaunch: true
+ - Key: Environment
+ Value: !Ref Environment
+ PropagateAtLaunch: true
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PropagateAtLaunch: true
+ ZMSEC2IncreaseGroupSizeScalingPolicy:
+ Type: "AWS::AutoScaling::ScalingPolicy"
+ Properties:
+ AdjustmentType: ChangeInCapacity
+ AutoScalingGroupName: !Ref ZMSEC2AutoScalingGroup
+ Cooldown: 180
+ ScalingAdjustment: 1
+ CPUAlarmHigh:
+ Type: AWS::CloudWatch::Alarm
+ Properties:
+ EvaluationPeriods: '5'
+ Statistic: Average
+ Threshold: '50'
+ Unit: Percent
+ AlarmDescription: Alarm if CPU too high or metric disappears indicating instance
+ is down
+ Period: '60'
+ AlarmActions:
+ - Ref: ZMSEC2IncreaseGroupSizeScalingPolicy
+ Namespace: AWS/EC2
+ Dimensions:
+ - Name: AutoScalingGroupName
+ Value:
+ Ref: ZMSEC2AutoScalingGroup
+ ComparisonOperator: GreaterThanThreshold
+ MetricName: CPUUtilization
+ ZMSEC2DecreaseGroupSizeScalingPolicy:
+ Type: "AWS::AutoScaling::ScalingPolicy"
+ Properties:
+ AdjustmentType: ChangeInCapacity
+ AutoScalingGroupName: !Ref ZMSEC2AutoScalingGroup
+ Cooldown: 300
+ ScalingAdjustment: -1
+ CPUAlarmLow:
+ Type: AWS::CloudWatch::Alarm
+ Properties:
+ EvaluationPeriods: '5'
+ Statistic: Average
+ Threshold: '20'
+ Unit: Percent
+ AlarmDescription: Alarm if CPU too low
+ Period: '60'
+ AlarmActions:
+ - Ref: ZMSEC2DecreaseGroupSizeScalingPolicy
+ Namespace: AWS/EC2
+ Dimensions:
+ - Name: AutoScalingGroupName
+ Value:
+ Ref: ZMSEC2AutoScalingGroup
+ ComparisonOperator: LessThanThreshold
+ MetricName: CPUUtilization
+ ZMSLaunchConfig:
+ Type: 'AWS::AutoScaling::LaunchConfiguration'
+ Properties:
+ AssociatePublicIpAddress: false
+ IamInstanceProfile: !Sub arn:aws:iam::${AWS::AccountId}:instance-profile/${ServiceRole}
+ ImageId: !Ref ImageId
+ KeyName: !Ref KeyName
+ InstanceType: !Ref Ec2InstanceType
+ EbsOptimized: !Ref EbsOptimized
+ SecurityGroups:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-ServerSecurityGroupID"
+ BlockDeviceMappings:
+ - DeviceName: "/dev/sda1"
+ Ebs:
+ VolumeSize: !Ref EbsVolumeSize
+ VolumeType: !Ref EbsVolumeType
+ DeleteOnTermination: true
+ InstanceMonitoring: true
\ No newline at end of file
diff --git a/aws-setup/zms-setup/cloud-formation/athenz-zms-aws-rds-setup.yaml b/aws-setup/zms-setup/cloud-formation/athenz-zms-aws-rds-setup.yaml
new file mode 100755
index 00000000000..e822a6306fa
--- /dev/null
+++ b/aws-setup/zms-setup/cloud-formation/athenz-zms-aws-rds-setup.yaml
@@ -0,0 +1,225 @@
+AWSTemplateFormatVersion: 2010-09-09
+Description: 'Athenz ZMS standard 2 Availabilty zone RDS configuration template'
+Parameters:
+ ServiceName:
+ Type: String
+ Description: The service name for ZMS server
+ Default: "zms"
+ GroupName:
+ Type: String
+ Description: The Athens domain for the account
+ Default: "Athenz"
+ ResourceStackName:
+ Type: String
+ Description: Name of Stack used to create AWS Resources
+ Environment:
+ Type: String
+ Description: The environment ZMS is running in
+ AllowedValues:
+ - prod
+ - stage
+ - dev
+ DatabaseName:
+ Type: String
+ Description: Database Name
+ Default: "zmsstore"
+ MinLength: "1"
+ MaxLength: "64"
+ AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
+ ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."
+ DatabaseUsername:
+ NoEcho: "true"
+ Type: String
+ Description: Database Username
+ Default: "dbuser"
+ MinLength: "1"
+ MaxLength: "16"
+ AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
+ ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."
+ DatabasePassword:
+ NoEcho: "true"
+ Type: String
+ Description: Database Password
+ Default: "dbpasswd"
+ MinLength: "1"
+ MaxLength: "41"
+ AllowedPattern: "[a-zA-Z0-9]+"
+ ConstraintDescription: "must contain only alphanumeric characters."
+ DatabaseInstanceClass:
+ Type: String
+ Description: "The database instance type"
+ Default: "db.t2.medium"
+ AllowedValues:
+ - db.t1.micro
+ - db.t1.micro
+ - db.t1.micro
+ - db.t1.micro
+ - db.m1.small
+ - db.m1.medium
+ - db.m1.large
+ - db.m1.xlarge
+ - db.m2.xlarge
+ - db.m2.2xlarge
+ - db.m2.4xlarge
+ - db.m3.medium
+ - db.m3.large
+ - db.m3.xlarge
+ - db.m3.2xlarge
+ - db.m4.large
+ - db.m4.xlarge
+ - db.m4.2xlarge
+ - db.m4.4xlarge
+ - db.m4.10xlarge
+ - db.r3.large
+ - db.r3.xlarge
+ - db.r3.2xlarge
+ - db.r3.4xlarge
+ - db.r3.8xlarge
+ - db.m2.xlarge
+ - db.m2.2xlarge
+ - db.m2.4xlarge
+ - db.cr1.8xlarge
+ - db.t2.micro
+ - db.t2.small
+ - db.t2.medium
+ - db.t2.large"
+ ConstraintDescription: "must select a valid database instance type."
+ EncryptDatabaseStorage:
+ Type: String
+ Description: Encrypt database storage
+ AllowedValues:
+ - "true"
+ - "false"
+ Default: "true"
+ Route53HostedZoneName:
+ Type: String
+ Description: The hosted zone name to place a CNAME entry for. Must end with a period. Empty string means do not create one.
+ Route53DatabaseRecordName:
+ Type: String
+ Description: The hosted records to be added
+Conditions:
+ CreateDNSRecordSet: !Not [!Equals [ !Ref Route53HostedZoneName, '']]
+ EnableDatabaseEncryption: !Equals [ !Ref EncryptDatabaseStorage , true]
+
+Resources:
+ DatabaseSubnetGroup:
+ Type: AWS::RDS::DBSubnetGroup
+ Properties:
+ DBSubnetGroupDescription: CloudFormation managed DB subnet group.
+ DBSubnetGroupName: !Sub ${Environment}-${ServiceName}-db-subnet
+ SubnetIds:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-PrivateSubnet01ID"
+ - Fn::ImportValue: !Sub "${ResourceStackName}-PrivateSubnet02ID"
+ DatabaseCluster:
+ Type: AWS::RDS::DBCluster
+ Properties:
+ Engine: aurora
+ DatabaseName: !Ref "DatabaseName"
+ MasterUsername: !Ref "DatabaseUsername"
+ MasterUserPassword: !Ref "DatabasePassword"
+ BackupRetentionPeriod: 7
+ PreferredBackupWindow: 01:00-02:00
+ PreferredMaintenanceWindow: mon:03:00-mon:04:00
+ DBSubnetGroupName: !Ref "DatabaseSubnetGroup"
+ VpcSecurityGroupIds: [!Ref "ZMSDBVPCSecurityGroup"]
+ StorageEncrypted: !Ref EncryptDatabaseStorage
+ KmsKeyId: !If [EnableDatabaseEncryption, !GetAtt DatabaseEncryptionKey.Arn, !Ref "AWS::NoValue"]
+ ZMSDBVPCSecurityGroup:
+ Type: "AWS::EC2::SecurityGroup"
+ Properties:
+ GroupName: !Sub ${GroupName}-${Environment}-rds-sg-${ServiceName}-${AWS::Region}
+ GroupDescription: 'ZMS public db security group'
+ SecurityGroupIngress:
+ - IpProtocol: TCP
+ FromPort: '3306'
+ ToPort: '3306'
+ CidrIp: '10.0.0.0/20'
+ VpcId:
+ Fn::ImportValue: !Sub "${ResourceStackName}-VPCID"
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-rds-sg-${ServiceName}-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ DatabaseEncryptionKey:
+ Type: 'AWS::KMS::Key'
+ Condition: EnableDatabaseEncryption
+ Properties:
+ Description: "KMS key for database encryption"
+ EnableKeyRotation: true
+ Enabled: true
+ KeyPolicy:
+ Version: 2012-10-17
+ Id: key-default-1
+ Statement:
+ - Sid: Enable IAM User Permissions
+ Effect: Allow
+ Principal:
+ AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
+ Action: 'kms:*'
+ Resource: '*'
+ Tags:
+ - Key: Name
+ Value: !Sub ${DatabaseName}-${AWS::Region}-encryption-key
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ DatabaseEncryptionKeyAlias:
+ Type: AWS::KMS::Alias
+ Condition: EnableDatabaseEncryption
+ Properties:
+ AliasName: !Sub alias/${DatabaseName}-${AWS::Region}-encryption-key
+ TargetKeyId: !Ref DatabaseEncryptionKey
+ DatabasePrimaryInstance:
+ Type: AWS::RDS::DBInstance
+ Properties:
+ Engine: aurora
+ DBClusterIdentifier: !Ref "DatabaseCluster"
+ DBInstanceClass: !Ref DatabaseInstanceClass
+ DBSubnetGroupName: !Ref "DatabaseSubnetGroup"
+ PubliclyAccessible: "false"
+ DBInstanceIdentifier: !Ref "DatabaseName"
+ Tags:
+ - Key: Name
+ Value: !Ref "DatabaseName"
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ DatabaseReplicaInstance:
+ Type: AWS::RDS::DBInstance
+ Properties:
+ Engine: aurora
+ DBClusterIdentifier: !Ref "DatabaseCluster"
+ DBInstanceClass: !Ref DatabaseInstanceClass
+ DBSubnetGroupName: !Ref "DatabaseSubnetGroup"
+ PubliclyAccessible: "false"
+ DBInstanceIdentifier: !Sub ${DatabaseName}-${AWS::Region}
+ Tags:
+ - Key: Name
+ Value: !Sub ${DatabaseName}-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ ZMSDatabaseRecordSet:
+ Type: AWS::Route53::RecordSet
+ Condition: CreateDNSRecordSet
+ Properties:
+ Comment: CNAME record for the ZMS DB.
+ HostedZoneName: !Ref Route53HostedZoneName
+ Name: !Ref Route53DatabaseRecordName
+ TTL: 60
+ Type: CNAME
+ ResourceRecords:
+ - !GetAtt DatabaseCluster.Endpoint.Address
+Outputs:
+ DatabasePrimaryInstanceEndpoint:
+ Description: Endpoint for primary database
+ Value: !GetAtt DatabasePrimaryInstance.Endpoint.Address
+ DatabaseReplicaInstanceEndpoint:
+ Description: Endpoint for primary database
+ Value: !GetAtt DatabaseReplicaInstance.Endpoint.Address
\ No newline at end of file
diff --git a/aws-setup/zms-setup/packer/aws/packer.json b/aws-setup/zms-setup/packer/aws/packer.json
new file mode 100755
index 00000000000..2a72f89f0ec
--- /dev/null
+++ b/aws-setup/zms-setup/packer/aws/packer.json
@@ -0,0 +1,105 @@
+{
+ "variables": {
+ "subnet_id":"subnet-xxxxxxxxx",
+ "vpc_id": "vpc-xxxxxxxxxxxxxx",
+ "aws_region": "{{env `AWS_REGION`}}",
+ "aws_ami_name": "zms-aws-cd-image",
+ "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
+ "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}",
+ "aws_session_token": "{{env `AWS_SESSION_TOKEN`}}",
+ "ssh_keypair_name":"keypair-name",
+ "ssh_private_key_file":"path to ssh key file",
+ "source_ami": "ami-02c71d7a"
+ },
+
+ "builders": [{
+ "access_key": "{{user `aws_access_key`}}",
+ "secret_key": "{{user `aws_secret_key`}}",
+ "token": "{{user `aws_session_token`}}",
+ "name": "amazon-ebs",
+ "ssh_username": "centos",
+ "ssh_keypair_name":"{{user `ssh_keypair_name`}}",
+ "ssh_private_key_file":"{{user `ssh_private_key_file`}}",
+ "type": "amazon-ebs",
+ "region": "{{user `aws_region`}}",
+ "source_ami": "{{user `source_ami`}}",
+ "ami_block_device_mappings": [
+ {
+ "device_name": "/dev/sda1",
+ "volume_type": "gp2",
+ "volume_size": 50,
+ "encrypted": true,
+ "delete_on_termination": true
+ }
+ ],
+ "instance_type": "t2.micro",
+ "ami_name": "{{user `aws_ami_name`}}",
+ "ami_description": "ZMS Image for cloud formation",
+ "associate_public_ip_address": "true",
+ "subnet_id": "{{ user `subnet_id` }}",
+ "vpc_id": "{{ user `vpc_id` }}"
+ }],
+
+ "provisioners": [
+ {
+ "type": "shell",
+ "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
+ "inline": [
+ "mkdir -p /opt",
+ "chmod a+w /opt"
+ ]
+ },
+ {
+ "type": "shell",
+ "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
+ "inline": [
+ "mkdir -p /opt/zms/tars",
+ "mkdir -p /opt/zms/jars",
+ "mkdir -p /opt/zms/logs",
+ "mkdir -p /opt/zms/webapps",
+ "mkdir -p /opt/zms/etc",
+ "mkdir -p /opt/zms/bin",
+ "mkdir -p /opt/zms/temp",
+ "mkdir -p /opt/zms/service",
+ "mkdir -p /opt/zms/conf",
+ "mkdir -p /opt/zms/conf/zms_server",
+ "mkdir /var/log/zms_server",
+ "chmod 777 /opt/zms -R"
+ ]
+ },
+ {
+ "type": "file",
+ "source": "build/bin/",
+ "destination": "/opt/zms/bin/"
+ },
+ {
+ "type": "file",
+ "source": "build/conf/",
+ "destination": "/opt/zms/conf/"
+ },
+ {
+ "type": "file",
+ "source": "build/service/",
+ "destination": "/opt/zms/service"
+ },
+ {
+ "type": "file",
+ "source": "tars/",
+ "destination": "/opt/zms/tars/"
+ },
+ {
+ "type": "shell",
+ "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
+ "inline": [
+ "ls -ltr /opt/"
+ ]
+ },
+ {
+ "type": "shell",
+ "scripts": [
+ "packer/scripts/setup.sh"
+ ],
+ "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E '{{ .Path }}'"
+ }
+ ]
+}
diff --git a/aws-setup/zms-setup/packer/scripts/setup.sh b/aws-setup/zms-setup/packer/scripts/setup.sh
new file mode 100755
index 00000000000..e6f380c0871
--- /dev/null
+++ b/aws-setup/zms-setup/packer/scripts/setup.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+set -xe
+
+# install epel
+
+sudo yum -y install epel-release
+sudo yum repolist
+
+# install aws_cli
+
+echo "install aws"
+sudo yum -y install python-pip
+sudo pip install awscli
+aws --version
+
+# install openjdk
+
+sudo yum -y install java-1.8.0-openjdk
+
+# setup our athenz group and user
+
+sudo groupadd athenz
+sudo useradd -g athenz athenz-zms
+
+# Copying jars, war and webdefault.xml files
+sudo tar -xzf /opt/zms/tars/athenz-zms-bin.tar.gz -C /opt/zms/tars/
+sudo ls -ltr /opt/zms/tars/
+sudo cp -r /opt/zms/tars/athenz-zms/lib/jars/ /opt/zms/
+sudo cp /opt/zms/tars/athenz-zms/etc/webdefault.xml /opt/zms/etc/
+sudo cp /opt/zms/tars/athenz-zms/webapps/zms.war /opt/zms/webapps/
+sudo cp /opt/zms/tars/athenz-zms/conf/zms_server/authorized_services.json /opt/zms/conf/zms_server/authorized_services.json
+sudo cp /opt/zms/tars/athenz-zms/conf/zms_server/solution_templates.json /opt/zms/conf/zms_server/solution_templates.json
+sudo cp -r /opt/zms/tars/athenz-zms/bin/linux/ /opt/zms/bin/
+
+# setup our zms service
+
+sudo mkdir /etc/zms
+sudo cp /opt/zms/service/zms.service /etc/zms/zms.service
+sudo systemctl enable /etc/zms/zms.service
+sudo cp /opt/zms/conf/zms-user /etc/sudoers.d/
+
+#set up aws logs
+
+curl https://s3.amazonaws.com//aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -o /opt/zms/logs/awslogs-agent-setup.py
+
+# make sure all files are owned by our user/group
+
+sudo chown -R athenz-zms:athenz /opt/zms
diff --git a/aws-setup/zts-setup/build/bin/athenz_conf.sh b/aws-setup/zts-setup/build/bin/athenz_conf.sh
new file mode 100755
index 00000000000..50b4a37c1c4
--- /dev/null
+++ b/aws-setup/zts-setup/build/bin/athenz_conf.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+#############
+# Usage: athenz_conf.sh [outputFile] [zts key bucket path] [zts url] [zms key bucket path] [zms url]
+# Generates Athenz conf file
+###############
+
+displayUsage() {
+ echo "athenz_conf.sh [outputFile] [ztsDataBucketName] [ztsUrl] [zmsUrl]";
+ echo 'athenz_conf.sh ./output.json athenz-zts-data-us-west-2 https://zts.athenz.com:4443/ https://zms.athenz.com:4443/';
+}
+
+if [ $# -ne 4 ]
+then
+ displayUsage
+ exit 1
+fi
+
+zms_public_key_file=zms_service_x509_key_public.pem
+zts_public_key_file=zts_service_x509_key_public.pem
+
+outputFile=$1
+ztsDataBucketName=$2
+ztsUrl=$3
+zmsUrl=$4
+
+# download CA certs from S3 bucket and store locally in temp directory
+aws s3 cp s3://$ztsDataBucketName/$zts_public_key_file /tmp/zts_pub_key
+aws s3 cp s3://$ztsDataBucketName/$zms_public_key_file /tmp/zms_pub_key
+
+sudo /opt/zts/bin/athenz-conf-aws -z $zmsUrl -t $ztsUrl -k /tmp/zms_pub_key -e /tmp/zts_pub_key -o $outputFile
diff --git a/aws-setup/zts-setup/build/bin/aws_config.sh b/aws-setup/zts-setup/build/bin/aws_config.sh
new file mode 100755
index 00000000000..0ab33023c9a
--- /dev/null
+++ b/aws-setup/zts-setup/build/bin/aws_config.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+aws_config_dir="$HOME/.aws"
+
+if [ -z "$HOME" ]; then
+ aws_config_dir="/athenz-zts/.aws"
+fi
+
+echo "Configuring aws config in $aws_config_dir"
+
+if [ ! -d "$aws_config_dir" ]; then
+ mkdir $aws_config_dir
+fi
+
+aws_config="[default]\nregion=$REGION"
+echo -e $aws_config > $aws_config_dir/config
diff --git a/aws-setup/zts-setup/build/bin/aws_init.sh b/aws-setup/zts-setup/build/bin/aws_init.sh
new file mode 100755
index 00000000000..3d6f34ba4bb
--- /dev/null
+++ b/aws-setup/zts-setup/build/bin/aws_init.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Exposes bucket names based on account and region
+# ENV
+# ZTS_DATA_BUCKET_NAME
+# ZTS_DOMAIN_BUCKET_NAME
+# ZTS_AUDIT_LOG_BUCKET_NAME
+# CERTSIGN_BUCKET_NAME
+# REGION
+
+set -e
+
+export REGION=`curl http://169.254.169.254/latest/dynamic/instance-identity/document|grep region|awk -F\" '{print $4}'`
+export ENV="dev"
+
+
+export ZTS_DATA_BUCKET_NAME="athenz-zts-data-bucket-name"
+export ZTS_AUDIT_LOG_BUCKET_NAME="athenz-audit-log-bucket-name"
+export ZTS_URL="https://zts.url:4443"
+export ZMS_URL="https://zms.url:4443"
+export RDS_MASTER="zts-rds-databasecluster-endpoint"
+export ZTS_TRUST_STORE_PATH="/opt/zts/conf/zts_truststore.jks"
+export TRUST_STORE_PATH="/opt/zts/conf/zts_java_truststore.jks"
+export KEY_STORE_PATH="/opt/zts/conf/zts_keystore.pkcs12"
+export JDK_CA_CERTS_PATH="/etc/alternatives/jre_1.8.0_openjdk/lib/security/cacerts"
+export JDK_CA_CERTS_PWD="changeit"
+export ATHENZ_CONF_PATH="/opt/zts/conf/athenz.conf"
+export DATASTORE_NAME="zts_store"
\ No newline at end of file
diff --git a/aws-setup/zts-setup/build/bin/aws_java_truststore_gen.sh b/aws-setup/zts-setup/build/bin/aws_java_truststore_gen.sh
new file mode 100755
index 00000000000..a2b45c110ad
--- /dev/null
+++ b/aws-setup/zts-setup/build/bin/aws_java_truststore_gen.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+#############
+# Usage: aws_java_truststore_gen.sh [jdk-ca-certs-path] [jdk-ca-certs-pwd] [bucket name] [trust store path]
+# Downloads CA certs from S3 bucket. Creates pkcs12 truststore for jetty.
+# Check for generated truststore: openssl pkcs12 -info -in /opt/zts/conf/ca.pkcs12
+###############
+
+display_usage() {
+ echo "aws_java_truststore_gen.sh [jdk-ca-certs-path] [jdk-ca-certs-pwd] [bucket name] [trust store path]";
+ echo "example: aws_java_truststore_gen.sh /opt/jvm/cacerts changeit oath-aws-athenz-sys-auth-certsign-us-west-2 /opt/zts/conf/ca.pkcs12"
+}
+
+cleanup() {
+ rm -f /tmp/service_rds_ca_certs
+ rm -f split_cacert-*
+}
+
+if [ $# -ne 4 ]
+then
+ display_usage
+ exit 1
+fi
+
+cleanup
+
+# define our S3 bucket filenames. we'll be using the same names
+# when we store files locally
+
+rds_ca_certs=service_rds_ca_certs
+zms_ca_certs=zms_service_x509_ca_certs
+
+jdk_ca_certs_path=$1
+jdk_ca_certs_pwd=$2
+bucket_name=$3
+trust_store_path=$4
+
+# download RDS CA certs from s3 bucket
+# aws s3 client will automatically decrypt the data
+
+aws s3 cp s3://$bucket_name/$rds_ca_certs /tmp/$rds_ca_certs
+aws s3 cp s3://$bucket_name/$zms_ca_certs /tmp/$zms_ca_certs
+
+# first copy the jdk ca certs into our given filename
+
+cp $jdk_ca_certs_path $trust_store_path
+rc=$?; if [[ $rc != 0 ]]; then cleanup; exit $rc; fi
+chmod u+w $trust_store_path
+
+# split the CA certs and add them to the truststore
+
+csplit -f split_cacert- -s -z /tmp/$rds_ca_certs '/^-----BEGIN CERTIFICATE-----/' {*}
+CERT_FILES=split_cacert-*
+for file in $CERT_FILES
+do
+ echo "Processing $file file..."
+ keytool -import -noprompt -alias $file -keystore $trust_store_path -file $file -storepass $jdk_ca_certs_pwd
+ rc=$?; if [[ $rc != 0 ]]; then cleanup; exit $rc; fi
+done
+
+keytool -import -noprompt -alias $zms_ca_certs -keystore $trust_store_path -file /tmp/$zms_ca_certs -storepass $jdk_ca_certs_pwd
+
+cleanup
+
+echo "successfully generated trust store"
diff --git a/aws-setup/zts-setup/build/bin/aws_zts_keystore_gen.sh b/aws-setup/zts-setup/build/bin/aws_zts_keystore_gen.sh
new file mode 100755
index 00000000000..618aa7ac4ee
--- /dev/null
+++ b/aws-setup/zts-setup/build/bin/aws_zts_keystore_gen.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+#############
+# Usage: aws_zts_keystore_gen.sh [bucket name] [key store path]
+# Downloads encrypted server.key and server.cert from private S3 bucket.
+# Decrypts and creates pkcs12 keystore for jetty.
+# Assumes that this script runs on an instance with a role that has policy
+# set to allow kms decrypt and read access to private S3 bucket.
+# Check for generated keystore: openssl pkcs12 -info -in jetty.pkcs12
+###############
+
+display_usage() {
+ echo "aws_zts_keystore_gen.sh [bucket name] [key store path]";
+ echo "example: aws_zts_keystore_gen.sh oath-aws-athenz-sys-auth-zts-prod-data-us-west-2 jetty.pkcs12"
+}
+
+cleanup() {
+ rm -f /tmp/service_x509_*
+}
+
+if [ $# -ne 2 ]
+then
+ display_usage
+ exit 1
+fi
+
+cleanup
+
+# define our S3 bucket filenames. we'll be using the same names
+# when we store files locally
+
+key_file=service_x509_key
+cert_file=service_x509_cert
+pwd_file=service_x509_store_pwd
+
+bucket_name=$1
+key_store_path=$2
+
+# download server cert and key from private s3 bucket
+# aws s3 client will automatically decrypt the data
+
+aws s3 cp s3://$bucket_name/$key_file /tmp/$key_file
+aws s3 cp s3://$bucket_name/$cert_file /tmp/$cert_file
+
+# extract the password the keystore
+
+aws s3 cp s3://$bucket_name/$pwd_file /tmp/$pwd_file
+key_store_pass=`cat /tmp/$pwd_file`
+
+# generate pkcs12 keystore using openssl
+
+openssl pkcs12 -export -inkey /tmp/$key_file -in /tmp/$cert_file -out $key_store_path -password pass:$key_store_pass -noiter -nomaciter
+openssl_status=$?
+
+cleanup
+
+if [ ! $openssl_status -eq 0 ]; then
+ echo "failed to generate key store"
+ exit 1
+fi
+
+echo "successfully generated key store"
+
diff --git a/aws-setup/zts-setup/build/bin/aws_zts_truststore_gen.sh b/aws-setup/zts-setup/build/bin/aws_zts_truststore_gen.sh
new file mode 100755
index 00000000000..4637b7d4ca7
--- /dev/null
+++ b/aws-setup/zts-setup/build/bin/aws_zts_truststore_gen.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+#############
+# Usage: aws_zts_truststore_gen.sh [bucket name] [trust store path]
+# Downloads CA certs from S3 bucket. Creates pkcs12 truststore for jetty.
+# Check for generated truststore: openssl pkcs12 -info -in /opt/zts/conf/ca.pkcs12
+###############
+
+display_usage() {
+ echo "aws_zts_truststore_gen.sh [bucket name] [trust store path]";
+ echo "example: aws_zts_truststore_gen.sh oath-aws-athenz-sys-auth-certsign-us-west-2 /opt/zts/conf/ca.pkcs12"
+}
+
+cleanup() {
+ rm -f /tmp/service_x509_ca_certs
+ rm -f split_cacert-*
+}
+
+if [ $# -ne 2 ]
+then
+ display_usage
+ exit 1
+fi
+
+cleanup
+
+# define our S3 bucket filenames. we'll be using the same names
+# when we store files locally
+
+ca_certs_file=service_x509_ca_certs
+pwd_file=service_x509_store_pwd
+
+bucket_name=$1
+trust_store_path=$2
+
+# download CA certs from s3 bucket
+# aws s3 client will automatically decrypt the data
+
+aws s3 cp s3://$bucket_name/$ca_certs_file /tmp/$ca_certs_file
+
+# extract the password the truststore
+
+aws s3 cp s3://$bucket_name/$pwd_file /tmp/$pwd_file
+trust_store_pass=`cat /tmp/$pwd_file`
+
+# split the CA certs and add them to the truststore
+
+csplit -f split_cacert- -s -z /tmp/$ca_certs_file '/^-----BEGIN CERTIFICATE-----/' {*}
+CERT_FILES=split_cacert-*
+for file in $CERT_FILES
+do
+ echo "Processing $file file..."
+ keytool -import -noprompt -alias $file -keystore $trust_store_path -file $file -storepass $trust_store_pass
+ rc=$?; if [[ $rc != 0 ]]; then cleanup; exit $rc; fi
+done
+
+cleanup
+
+echo "successfully generated trust store"
diff --git a/aws-setup/zts-setup/build/bin/initialize_zts.sh b/aws-setup/zts-setup/build/bin/initialize_zts.sh
new file mode 100755
index 00000000000..d2b5546a20d
--- /dev/null
+++ b/aws-setup/zts-setup/build/bin/initialize_zts.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# Usage: initialize_zts.sh
+
+#Runs athenz.conf.sh to get athenz.conf file
+# Runs aws_zts_truststore_gen.sh to get trust store
+# Runs aws_java_truststore_gen.sh to get java trust store
+# Runs aws_zts_keystore_gen.sh to generate key store.
+
+
+set -e
+
+echo "creating aws config"
+/opt/zts/bin/aws_config.sh
+
+echo "initializing aws cloudwatch log setup"
+sudo python /opt/zts/logs/awslogs-agent-setup.py -n -r $REGION -c /opt/zts/conf/awslogs.conf
+
+cd /opt/zts/temp
+
+echo "generating athenz conf"
+/opt/zts/bin/athenz_conf.sh $ATHENZ_CONF_PATH $ZTS_DATA_BUCKET_NAME $ZTS_URL $ZMS_URL
+
+echo "generating zts trust store /opt/zts/bin/aws_zts_truststore_gen.sh $ZTS_DATA_BUCKET_NAME $ZTS_TRUST_STORE_PATH"
+rm -f $ZTS_TRUST_STORE_PATH
+/opt/zts/bin/aws_zts_truststore_gen.sh $ZTS_DATA_BUCKET_NAME $ZTS_TRUST_STORE_PATH
+
+echo "generating java trust store /opt/zts/bin/aws_java_truststore_gen.sh $JDK_CA_CERTS_PATH $JDK_CA_CERTS_PWD $ZTS_DATA_BUCKET_NAME $TRUST_STORE_PATH"
+rm -f $TRUST_STORE_PATH
+/opt/zts/bin/aws_java_truststore_gen.sh $JDK_CA_CERTS_PATH $JDK_CA_CERTS_PWD $ZTS_DATA_BUCKET_NAME $TRUST_STORE_PATH
+
+echo "generating zts key store /opt/zts/bin/aws_zts_keystore_gen.sh $ZTS_DATA_BUCKET_NAME $KEY_STORE_PATH"
+rm -f $KEY_STORE_PATH
+/opt/zts/bin/aws_zts_keystore_gen.sh $ZTS_DATA_BUCKET_NAME $KEY_STORE_PATH
+
+# echo "Downloading self cert signer key"
+# aws s3 cp s3://$bucket_name/self_cert_signer_key /opt/zts/conf/self_cert_signer_key
+
+
diff --git a/aws-setup/zts-setup/build/bin/zts.sh b/aws-setup/zts-setup/build/bin/zts.sh
new file mode 100755
index 00000000000..5015ead8783
--- /dev/null
+++ b/aws-setup/zts-setup/build/bin/zts.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+set -e
+
+source /opt/zts/bin/aws_init.sh
+
+/opt/zts/bin/initialize_zts.sh
+cd /opt/zts
+
+# setup our database cluster endpoint and other environment
+# specific settings. us-west-2 is our primary region while
+# us-east-1 is our backup read-only region
+
+
+
+JAVA_OPTS="-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+PrintGCDetails -Xloggc:/opt/zts/logs/gc.log"
+JAVA_OPTS="${JAVA_OPTS} -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation"
+JAVA_OPTS="${JAVA_OPTS} -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=4M"
+JAVA_OPTS="${JAVA_OPTS} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/zts/logs"
+
+java -server $JAVA_OPTS \
+ -Dathenz.root_dir=/opt/zts \
+ -Dathenz.zts.root_dir=/opt/zts \
+ -Dlogback.configurationFile=/opt/zts/conf/logback.xml \
+ -Dathenz.prop_file=/opt/zts/conf/athenz.properties \
+ -Dathenz.zts.prop_file=/opt/zts/conf/zts.properties \ \
+ -Dathenz.zts.cert_jdbc_store=jdbc:mysql://${RDS_MASTER}:3306/${DATASTORE_NAME} \
+ -Dathenz.aws.zts.bucket_name=$ZTS_DATA_BUCKET_NAME \
+ -Dathenz.zts.cert_jdbc_app_name=$ZTS_DATA_BUCKET_NAME \
+ -Dathenz.zts.ssl_key_store_password_appname=$ZTS_DATA_BUCKET_NAME \
+ -Dathenz.zts.ssl_trust_store_password_appname=$ZTS_DATA_BUCKET_NAME \
+ -Dathenz.ssl_key_store_password_appname=$ZTS_DATA_BUCKET_NAME \
+ -Dathenz.ssl_trust_store_password_appname=$ZTS_DATA_BUCKET_NAME \
+ -Dathenz.zts.aws_region_name=$REGION \
+ -Dathenz.zts.read_only_mode=false \
+ -classpath ":/opt/zts/jars/*:" \
+ com.yahoo.athenz.container.AthenzJettyContainer
diff --git a/aws-setup/zts-setup/build/conf/athenz.properties b/aws-setup/zts-setup/build/conf/athenz.properties
new file mode 100755
index 00000000000..b4cba25bbc1
--- /dev/null
+++ b/aws-setup/zts-setup/build/conf/athenz.properties
@@ -0,0 +1,148 @@
+# Athenz Jetty Container properties file.
+# If there is a value specified in the commented property line,
+# then it indicates the default value
+
+# The TLS port that Jetty will listen on for HTTPS connection
+athenz.tls_port=4443
+
+# The standard HTTP port for Jetty - disabled by default
+athenz.port=0
+
+# Port for requesting /status health check. If this setting is
+# not specified, then the request will be handled by either http
+# or https ports specified in the configuration. However, if this
+# status port is specified and is different than the configured
+# http and https ports, then /status endpoint will only be handled
+# on this port and all other requests will be rejected. Similarly,
+# /status endpoint will not be allowed on configured http/https
+# ports. The status port will be either http or https depending
+# which port is specified for data access. If both http and https
+# ports are specified, https will be selected for the protocol.
+athenz.status_port=8443
+
+# Set the number of days before rotated access log files are deleted
+athenz.access_log_retain_days=31
+
+# Format of the access log filename
+athenz.access_log_name=access.yyyy_MM_dd.log
+
+# If specified, the server will use SLF4J logger with the specified name
+# to log events instead of using Jetty's NCSARequestLog class.
+# The administrator then must configure the specified logger in the logback.xml
+athenz.access_slf4j_logger=
+
+# Directory to store access log files
+athenz.access_log_dir=/opt/zts/logs
+
+# Key Manager password
+#athenz.ssl_key_manager_password=
+
+# The path to the keystore file that contains the server's certificate
+athenz.ssl_key_store=/opt/zts/conf/zts_keystore.pkcs12
+
+# Specifies the type for the keystore specified in the
+# athenz.ssl_key_store property
+athenz.ssl_key_store_type=PKCS12
+
+# Password for the keystore specified in the athenz.ssl_key_store property
+athenz.ssl_key_store_password=service_x509_store_pwd
+
+# The path to the trust store file that contains CA certificates
+# trusted by this Jetty instance
+athenz.ssl_trust_store=/opt/zts/conf/zts_truststore.jks
+
+# Specifies the type for the truststore specified in the
+# athenz.ssl_trust_store property
+athenz.ssl_trust_store_type=JKS
+
+# Password for the truststore specified in the athenz.ssl_trust_store property
+athenz.ssl_trust_store_password=service_x509_store_pwd
+
+# Specifies whether or not for data requests the server
+# would require TLS client authentication rather than
+# just wanting it
+athenz.ssl_need_client_auth=false
+
+# Private key store to extract the passwords defined for
+# java keystore and truststore
+athenz.private_keystore_factory_class=com.yahoo.athenz.auth.impl.aws.AwsPrivateKeyStoreFactory
+
+# Specifies the truststore used by java clients when communicating
+# with other AWS services like S3 or RDS. This should be the
+# JDK shipped truststore + AWS RDS CA truststore
+javax.net.ssl.trustStore=/opt/zts/conf/zts_java_truststore.jks
+javax.net.ssl.trustStorePassword=changeit
+
+# List of excluded cipher suites from TLS negotiation
+#athenz.ssl_excluded_cipher_suites=
+
+# List of cipher suites supported for TLS negotiation
+athenz.ssl_included_cipher_suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA
+
+# Comma separated list of excluded ssl protocols
+#athenz.ssl_excluded_protocols=SSLv2,SSLv3
+
+# Configure if client TLS renegotiation is allowed or not
+athenz.ssl_renegotiation_allowed=false
+
+# Enable OCSP support
+#athenz.ssl_enable_ocsp=false
+
+# In milliseconds how long that connector will be allowed to
+# remain idle with no traffic before it is shutdown
+athenz.http_idle_timeout=30000
+
+# Boolean setting to specify whether or not the server should
+# send the Server header in response
+athenz.http_send_server_version=false
+
+# Boolean setting to specify whether or not the server should
+# include the Date in HTTP headers
+athenz.http_send_date_header=false
+
+# The size in bytes of the output buffer used to aggregate HTTP output
+#athenz.http_output_buffer_size=32768
+
+# The maximum allowed size in bytes for a HTTP request header
+#athenz.http_reqeust_header_size=8192
+
+# The maximum allowed size in bytes for a HTTP response header
+#athenz.http_response_header_size=8192
+
+# For HTTP access specifies the IP address/Host for service to listen on.
+# This could be necessary, for example, if the system administrator
+# wants some proxy server (e.g. ATS) to handle TLS traffic and configure
+# Jetty to listen on 127.0.0.1 loopback address only for HTTP connections
+# from that proxy server
+#athenz.listen_host=
+
+# Boolean flag to indicate whether or not the container should honor
+# the Keep Alive connection option or just connections right away
+#athenz.keep_alive=false
+
+# Max number of threads Jetty is allowed to spawn to handle incoming requests
+athenz.http_max_threads=1024
+
+# Specify the FQDN/hostname of the server. This will bereported as part
+# of the server banner notification in logs
+#athenz.hostname=
+
+# Default home directory for embedded Jetty Deployer. The container will look
+# for any servlets in the webapps subdirectory of the configured directory
+athenz.jetty_home=/opt/zts
+
+# Boolean flag to enable debug log entries when deploying webapps
+#athenz.debug=false
+
+# Comma separated liste of uris that are accessed by health check
+# system. Used by the simple file based health check filter that
+# returns 200/404 if the file exists or not
+athenz.health_check_uri_list=/status
+
+# Directory name where the files specified in the athenz.health_check_uri_list
+# setting are checked for
+athenz.health_check_path=/opt/zts
+
+# Enable Proxy Protocol (used by HAProxy and environments such as Amazon Elastic Cloud)
+# for the jetty container.
+athenz.proxy_protocol=true
diff --git a/aws-setup/zts-setup/build/conf/aws_public.crt b/aws-setup/zts-setup/build/conf/aws_public.crt
new file mode 100755
index 00000000000..0ff9d47a900
--- /dev/null
+++ b/aws-setup/zts-setup/build/conf/aws_public.crt
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC7TCCAq0CCQCWukjZ5V4aZzAJBgcqhkjOOAQDMFwxCzAJBgNVBAYTAlVTMRkw
+FwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYD
+VQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAeFw0xMjAxMDUxMjU2MTJaFw0z
+ODAxMDUxMjU2MTJaMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9u
+IFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNl
+cnZpY2VzIExMQzCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQCjkvcS2bb1VQ4yt/5e
+ih5OO6kK/n1Lzllr7D8ZwtQP8fOEpp5E2ng+D6Ud1Z1gYipr58Kj3nssSNpI6bX3
+VyIQzK7wLclnd/YozqNNmgIyZecN7EglK9ITHJLP+x8FtUpt3QbyYXJdmVMegN6P
+hviYt5JH/nYl4hh3Pa1HJdskgQIVALVJ3ER11+Ko4tP6nwvHwh6+ERYRAoGBAI1j
+k+tkqMVHuAFcvAGKocTgsjJem6/5qomzJuKDmbJNu9Qxw3rAotXau8Qe+MBcJl/U
+hhy1KHVpCGl9fueQ2s6IL0CaO/buycU1CiYQk40KNHCcHfNiZbdlx1E9rpUp7bnF
+lRa2v1ntMX3caRVDdbtPEWmdxSCYsYFDk4mZrOLBA4GEAAKBgEbmeve5f8LIE/Gf
+MNmP9CM5eovQOGx5ho8WqD+aTebs+k2tn92BBPqeZqpWRa5P/+jrdKml1qx4llHW
+MXrs3IgIb6+hUIB+S8dz8/mmO0bpr76RoZVCXYab2CZedFut7qc3WUH9+EUAH5mw
+vSeDCOUMYQR7R9LINYwouHIziqQYMAkGByqGSM44BAMDLwAwLAIUWXBlk40xTwSw
+7HX32MxXYruse9ACFBNGmdX2ZBrVNGrN9N2f6ROk0k9K
+ -----END CERTIFICATE-----
\ No newline at end of file
diff --git a/aws-setup/zts-setup/build/conf/awslogs.conf b/aws-setup/zts-setup/build/conf/awslogs.conf
new file mode 100755
index 00000000000..3369074d776
--- /dev/null
+++ b/aws-setup/zts-setup/build/conf/awslogs.conf
@@ -0,0 +1,27 @@
+[general]
+state_file = /var/awslogs/state/agent-state
+
+[syslog]
+file = /var/log/messages
+log_group_name = athenz-zts-service-syslog
+log_stream_name = {instance_id}
+datetime_format = %b %d %H:%M:%S
+
+[access]
+file = /opt/zts/logs/access*.log
+log_group_name = athenz-zts-service-access
+log_stream_name = {instance_id}
+datetime_format = %b %d %H:%M:%S
+
+[server]
+file = /opt/zts/logs/zts_server/server*.log
+log_group_name = athenz-zts-service-server
+log_stream_name = {instance_id}
+datetime_format = %b %d %H:%M:%S
+
+[gc]
+file = /opt/zts/logs/gc.log.*
+log_group_name = athenz-zts-service-gc
+log_stream_name = {instance_id}
+datetime_format = %b %d %H:%M:%S
+==
diff --git a/aws-setup/zts-setup/build/conf/logback.xml b/aws-setup/zts-setup/build/conf/logback.xml
new file mode 100755
index 00000000000..502cf3a803a
--- /dev/null
+++ b/aws-setup/zts-setup/build/conf/logback.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+ ${LOG_DIR}/server.log
+ true
+
+
+ ${LOG_DIR}/server.%d.log
+ 7
+ true
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n
+
+
+
+
+
+
+ ${LOG_DIR}/audit.log
+ true
+
+
+ ${LOG_DIR}/audit.%d.log
+ 30
+ true
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aws-setup/zts-setup/build/conf/zts-user b/aws-setup/zts-setup/build/conf/zts-user
new file mode 100755
index 00000000000..c4fa502900c
--- /dev/null
+++ b/aws-setup/zts-setup/build/conf/zts-user
@@ -0,0 +1 @@
+athenz-zts ALL=(ALL) NOPASSWD: ALL
\ No newline at end of file
diff --git a/aws-setup/zts-setup/build/conf/zts.properties b/aws-setup/zts-setup/build/conf/zts.properties
new file mode 100755
index 00000000000..24951b5ec84
--- /dev/null
+++ b/aws-setup/zts-setup/build/conf/zts.properties
@@ -0,0 +1,337 @@
+# Athenz ZTS Service properties file.
+# If there is a value specified in the commented property line,
+# then it indicates the default value
+
+# Specifies the user domain name for the current installation
+#athenz.user_domain=user
+
+# Specifies the user domain alias name for the current installation
+#athenz.user_domain_alias=yby
+
+# ZTS is running within AWS so enable features such as getting temporary
+# credentials, etc.
+athenz.zts.aws_enabled=true
+
+# If ZTS is running within AWS and we need to validate the host identity document
+# before we issue a TLS certificate for a service identified by its IAM role,
+# the server verifies that the instance was booted within the configured number
+# of seconds
+athenz.zts.aws_boot_time_offset=1800
+
+# If ZTS is running within AWS, this setting specifies path a file that includes
+# the AWS Public certificate that is needed to verify host identity documents
+# provided by AWS.
+athenz.zts.aws_public_cert=/opt/zts/conf/aws_public.crt
+
+# If ZTS is running within AWS, this setting specifies the DNS suffix
+# that the AWS provider will use to validate all hostnames in the CSR
+athenz.zts.aws_dns_suffix=aws.oath.cloud
+
+# Comma separated list of authority implementation classes to support
+# authenticating principals in ZTS
+# athenz.zts.authority_classes=com.yahoo.athenz.auth.oath.impl.CertificateOktaAuthority,com.yahoo.athenz.auth.impl.CertificateAuthority
+
+# If File Private Key store implementation is used in the Server,
+# this setting specifies the path to the PEM encoded ZTS Server
+# private key file (both RSA and EC privates keys are supported)
+#athenz.auth.private_key_store.private_key=
+
+# If File Private Key store implementation is used in the Server,
+# this setting specifies the key identifier for the private key
+# configured by the athenz.auth.private_key_store.private_key
+# property
+#athenz.auth.private_key_store.private_key_id=
+
+# Key Manager password
+#athenz.zts.ssl_key_manager_password=
+
+# The path to the keystore file that contains the client's private key
+# and certificate. Currently this is only used by the HttpCertSigner
+# class implementation.
+athenz.zts.ssl_key_store=/opt/zts/conf/zts_keystore.pkcs12
+
+# Specifies the type for the keystore specified in the
+# athenz.zts.ssl_key_store property
+athenz.zts.ssl_key_store_type=PKCS12
+
+# Password for the keystore specified in the athenz.zts.ssl_key_store property
+athenz.zts.ssl_key_store_password=service_x509_store_pwd
+
+# The path to the trust store file that contains CA certificates
+# trusted by the http client running within this ZTS instance
+athenz.zts.ssl_trust_store=/opt/zts/conf/zts_truststore.jks
+
+# Type for the truststore specified in the athenz.zts.ssl_trust_store property
+athenz.zts.ssl_trust_store_type=JKS
+
+# Password for the truststore specified in the athenz.zts.ssl_trust_store property
+athenz.zts.ssl_trust_store_password=service_x509_store_pwd
+
+# Specifies the location for the athenz.conf file used by the ZMS Client
+# library to determine what ZMS server to contact to.
+athenz.athenz_conf=/opt/zts/conf/athenz.conf
+
+# If specified, this setting overrides the ZMS Server url value for the
+# ZMS Client as retrieved from the athenz.conf file
+#athenz.zts.zms_url=https://test.athens.aws.oath.cloud:4443/
+
+# SelfCertSignerFactory implementation - if this factory class is used
+# is used for the CertSigner implementation (athenz.zts.cert_signer_factory_class
+# property), this setting specifies the private key filename that is used to sign
+# certificate requests.
+# athenz.zts.self_signer_private_key_fname=/opt/zts/conf/self_cert_signer_key
+
+# SelfCertSignerFactory implementation - if this factory class is used
+# is used for the CertSigner implementation (athenz.zts.cert_signer_factory_class
+# property), this setting specifies the private key password that is used to sign
+# certificate requests.
+#athenz.zts.self_signer_private_key_password=
+
+# SelfCertSignerFactory implementation - if this factory class is used
+# is used for the CertSigner implementation (athenz.zts.cert_signer_factory_class
+# property), this setting specifies the dn for the CA certificate that ZTS
+# will use
+# athenz.zts.self_signer_cert_dn=C=US,ST=CA,L=Sunnyvale,O=Oath,OU=Athenz,CN=zts.aws.oath.cloud.
+
+# HttpCertSignerFactory implementation - if this factory class is used
+# for the for the CertSigner implementation (athenz.zts.cert_signer_factory_class
+# property), this setting specifies the base uri for the Certificate Signer Service
+#athenz.zts.certsign_base_uri=
+
+# HttpCertSignerFactory implementation - if this factory class is used
+# for the CertSigner implementation (athenz.zts.cert_signer_factory_class
+# property), this setting specifies in seconds the connect timeout
+#athenz.zts.certsign_connect_timeout=10
+
+# HttpCertSignerFactory implementation - if this factory class is used
+# for the CertSigner implementation (athenz.zts.cert_signer_factory_class
+# property), this setting specifies in seconds the request timeout.
+# We're setting the initial value to a small on so we know right away
+# if our idle connection has been been closed by cert signer and we'll
+# use our retry setting to retry with a max timout of 30 seconds.
+#athenz.zts.certsign_request_timeout=5
+
+# HttpCertSignerFactory implementation - if this factory class is used
+# for the CertSigner implementation (athenz.zts.cert_signer_factory_class
+# property), this setting specifies the number of times the request
+# should be retried if it's not completed with the requested timeout value
+#athenz.zts.certsign_retry_count=3
+
+# Specifies the factory class that implements the Metrics interface
+# used by the ZTS Server to report stats
+athenz.zts.metric_factory_class=com.yahoo.athenz.common.metrics.impl.NoOpMetricFactory
+
+# Specifies the factory class that implements the AuditLoggerFactory
+# interface used by the ZTS Server to log all changes to domain
+# data for auditing purposes
+athenz.zts.audit_logger_factory_class=com.yahoo.athenz.common.server.log.impl.DefaultAuditLoggerFactory
+
+# Specifies the factory class that implements the PrivateKeyStoreFactory
+# interface used by the ZTS Server to get access to its host specific
+# private key
+athenz.zts.private_key_store_factory_class=com.yahoo.athenz.auth.impl.aws.AwsPrivateKeyStoreFactory
+
+# Specifies the factory class that implements CertSignerFactory
+# interface used by the ZTS Server to sign any certificate requests
+athenz.zts.cert_signer_factory_class=com.yahoo.athenz.zts.cert.impl.SelfCertSignerFactory
+
+# Specifies the factory class that implements ChangeLogStoreFactory
+# interface used by the ZTS Server to retrieve the latest changes
+# from the ZMS Server and save them locally
+athenz.zts.change_log_store_factory_class=com.yahoo.athenz.zts.store.impl.ZMSChangeLogStoreFactory
+
+# Specifies the directory for storing zms domain json documents when
+# ZMSFileChangeLogStoreFactory is configured for the change log factory
+# class (athenz.zts.data_change_log_store_factory_class property)
+athenz.zts.change_log_store_dir=/opt/zts/domains
+
+
+# Boolean setting to force users to request role tokens for specific
+# roles rather than for domain which will includes all the roles the
+# given principal has access in that domain
+#athenz.zts.least_privilege_principle=false
+
+# Specifies the maximum expiry timeout that a client can ask for when
+# requesting a role token. If the client asks for a longer timeout, the
+# server will automatically replace the value with this one
+#athenz.zts.role_token_max_timeout=2592000
+
+# Specifies the default expiry timeout for role tokens when the client
+# does not specify any timeout parameters
+#athenz.zts.role_token_default_timeout=7200
+
+# Specifies the expiry timeout for signed policy documents that
+# ZTS Server signs and returns to ZPU clients
+#athenz.zts.signed_policy_timeout=604800
+
+# Comma separated list of authorized proxy principals
+#athenz.zts.authorized_proxy_users=
+
+# Specifies the service name that the ostk instance documents are
+# signed with.
+#athenz.zts.ostk_host_signer_service=
+
+# If the ZTS servlet is deployed along other servlets that may
+# run on non-TLS ports, this setting forces that requests to
+# ZTS are only accepted on secure TLS ports.
+#athenz.zts.secure_requests_only=true
+
+# Comma separated list of hostname suffixes that providers
+# are allowed to use for their verifiers
+athenz.zts.provider_endpoints=athenz.cloud
+
+# Specifies timeout in seconds for NTokens issued by ZTS
+# Server as part of the Instance bootstrap request
+#athenz.zts.instance_token_timeout=86400
+
+# Specifies in seconds how often to query ZMS Server for updates
+# The default value is 60 seconds
+#athenz.zts.zms_domain_update_timeout=60
+
+# Specifies in seconds how often to query ZMS Server for the full
+# list of domains to determine the deleted domains
+# The default value is 3600 seconds
+#athenz.zts.zms_domain_delete_timeout=3600
+
+# JDBC URL where the ZTS Server will store certificate records for
+# revocation checks
+# jdbc:mysql://localhost:3306/zts - specifies MySQL instance
+#athenz.zts.cert_jdbc_store=
+
+# If the jdbcstore is pointing to a MySQL server then this specifies
+# the name of the user that has full access to the zts database
+athenz.zts.cert_jdbc_user=athenz-zts
+
+# If the jdbcstore is pointing to a MySQL server then this specifies
+# the password for the jdbc user that has been granted full access
+# to the configured zts database
+athenz.zts.cert_jdbc_password=db_user_data
+
+# Specifies the factory class for the certificate record factory
+# class implementation
+athenz.zts.cert_record_store_factory_class=com.yahoo.athenz.zts.cert.impl.JDBCCertRecordStoreFactory
+
+# If the athenz.zts.cert_record_store_factory_class property is using
+# the aws rds mysql object store factory identified with
+# com.yahoo.athenz.zts.store.impl.AWSObjectStoreFactory, then
+# this setting specifies AWS RDS instance hostname.
+# The database server must be initialized with the ZTS
+# server schema.
+# athenz.zts.aws_rds_master_instance=
+
+# If the athenz.zts.cert_record_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# the database user configured with IAM Role AWS authentication
+# and full access to the zts store database
+# athenz.zts.aws_rds_user=zts
+
+# If the athenz.zts.cert_record_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# the IMA role that has been enabled for authentication
+# athenz.zts.aws_rds_iam_role=athenz.zts-service
+
+# If the athenz.zts.cert_record_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# the port number for the RDL database instance
+# athenz.zts.aws_rds_master_port=3306
+
+# If the athenz.zts.cert_record_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# the database engine used in rds
+# athenz.zts.aws_rds_engine=mysql
+
+# If the athenz.zts.cert_record_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# the database name in rds
+# athenz.zts.aws_rds_database=zts_store
+
+# If the athenz.zts.cert_record_store_factory_class property is using
+# the aws rds mysql object store then this setting specifies
+# in seconds how often to update the aws credentials for the IAM role
+athenz.zts.aws_rds_creds_refresh_time=300
+
+# The maximum number of seconds that the server should wait
+# for the certificate store connection object to return its results
+athenz.zts.cert_op_timeout=60
+
+# When requesting TLS certificates for their corresponding NTokens,
+# services must this dns suffix in their CSRs
+athenz.zts.cert_dns_suffix=aws.oath.cloud
+
+# Kerberos Authority Service Principal
+#athenz.auth.kerberos.service_principal=
+
+# Kerberos Authority location of keytab file
+#athenz.auth.kerberos.keytab_location=
+
+# Kerberos Authority debug boolean state
+#athenz.auth.kerberos.debug=false
+
+# Kerberos Authority - if there is a jaas.conf whose path is specified by
+# the system property java.security.auth.login.config then this setting
+# specifies the config section name to be used for the authority
+#athenz.auth.kerberos.jaas_cfg_section=
+
+# Kerberos Authority - login callback handler class
+#athenz.auth.kerberos.login_callback_handler_class=
+
+# Kerberos Authority - boolean flag whether or not to renew TGT
+#athenz.auth.kerberos.renewTGT=true
+
+# Kerberos Authority - boolean flag whether or not using ticket cache
+#athenz.auth.kerberos.use_ticket_cache=true
+
+# Kerberos Authority - file path for the ticket cache data
+#athenz.auth.kerberos.ticket_cache_name=
+
+# Kerberos Authority - in milliseconds the login window time for re-logins
+#athenz.auth.kerberos.login_window=60000
+
+# Kerberos Authority - privileged action class name
+#athenz.auth.kerberos.krb_privileged_action_class=
+
+# Kerberos Authority - the realm for kerberos users (this could be a realm
+# that regular users (also authenticated as part of UserAuthority) are part of
+#athenz.auth.kerberos.user_realm=
+
+# Kerberos Authority - the domain name for users that are only authenticated
+# by this authority
+#athenz.auth.kerberos.krb_user_domain=ygrid
+
+# Kerberos Authority - the realm name for users that are only authenticated
+# by this authority
+#athenz.auth.kerberos.krb_user_realm=
+
+# Comma separated list of URIs that require authentication according to the RDL
+# but we want the server to make the authentication as optional. The URI can
+# include regex values based on + character to match resource URIs
+# for example, /zts/v1/domain/.+/service
+athenz.zts.no_auth_uri_list=/zts/v1/status
+
+# Filename that includes list of IP address blocks that are
+# authorized to carry out cert refresh operation for manually
+# generated certs
+#athenz.zts.cert_refresh_ip_fname=/opt/zts/conf/cert_refresh_ipblocks.json
+
+# Filename that includes list of IP address blocks that are
+# authorized to carry out instance register operations
+#athenz.zts.instance_cert_ip_fname=/opt/zts/conf/instance_cert_ipblocks.json
+
+# list of accepted client ids for Okta authority
+#athenz.auth_core.cert_okta.client_ids_fname=/opt/zts/conf/client_map_ids.txt
+
+# okta authority url
+#athenz.auth_core.cert_okta.url=https://oath.okta.com/oauth2/aus3veicdv5jKkozw1t7/
+
+# zts service athenz private key path
+#athenz.zts.service_private_key_path=/var/lib/sia/keys/athenz.zts.key.pem
+
+# zts service athenz certificate path
+#athenz.zts.service_certificate_path=/var/lib/sia/certs/athenz.zts.cert.pem
+
+# If configured, specifies a file name that contains the bundle of Athenz
+# CA certificates. This is useful when there are multiple Athenz instances
+# running in different regions/locations and each region/location has its own
+# CA certificate and during instance register/refresh operation we want to
+# return the full set of CA certs
+#athenz.zts.x509_ca_cert_fname=/opt/zts/conf/athenz_certificate_bundle.pem
diff --git a/aws-setup/zts-setup/build/service/zts.service b/aws-setup/zts-setup/build/service/zts.service
new file mode 100755
index 00000000000..e1e03c37ea9
--- /dev/null
+++ b/aws-setup/zts-setup/build/service/zts.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Athenz ZTS Service
+Wants=network-online.target ntpd.service
+After=network-online.target
+
+[Service]
+ExecStart=/opt/zts/bin/zts.sh
+Restart=on-failure
+RestartSec=20
+User=athenz-zts
+Group=athenz
+
+[Install]
+WantedBy=multi-user.target
diff --git a/aws-setup/zts-setup/cloud-formation/athens-zts-aws-instance-deployment.yaml b/aws-setup/zts-setup/cloud-formation/athens-zts-aws-instance-deployment.yaml
new file mode 100644
index 00000000000..1e0cbd89aee
--- /dev/null
+++ b/aws-setup/zts-setup/cloud-formation/athens-zts-aws-instance-deployment.yaml
@@ -0,0 +1,179 @@
+Description: 'Athenz ZTS standard 2 Availabilty zone instance deployment template'
+Parameters:
+ ServiceRole:
+ Type: String
+ Description: The ZTS Service IAM Role Name
+ Default: "athenz.zts-service"
+ KeyName:
+ Type: String
+ Description: The EC2 key pair for the instance
+ ServiceName:
+ Type: String
+ Description: The service name for ZTS server
+ Default: "zts"
+ ResourceStackName:
+ Type: String
+ Description: Name of Stack used to create AWS Resources
+ Environment:
+ Type: String
+ Description: The environment ZTS is running in
+ AllowedValues:
+ - prod
+ - stage
+ - dev
+ ImageId:
+ Type: AWS::EC2::Image::Id
+ Description: "The ImageId to use for the EC2 instance. Should be a format like ami-XXXXXXXX"
+ AutoScalingMinSize:
+ Type: String
+ Description: The minimum instances for auto scaling
+ Default: "2"
+ AutoScalingMaxSize:
+ Type: String
+ Description: The maximum instances for auto scaling
+ Default: "4"
+ AutoScalingDesiredCapacity:
+ Type: String
+ Description: The desired number of instances
+ Default: "2"
+ EbsOptimized:
+ Type: String
+ Description: TIf EBS is to be optimized
+ AllowedValues:
+ - "true"
+ - "false"
+ Default: "false"
+ Ec2InstanceType:
+ Type: String
+ Description: The instance type to use for the host
+ Default: t2.large
+ AllowedValues:
+ - t2.nano
+ - t2.micro
+ - t2.small
+ - t2.medium
+ - t2.large
+ - t2.xlarge
+ - t2.2xlarge
+ - m4.large
+ - m4.xlarge
+ - m4.2xlarge
+ - m4.4xlarge
+ - m4.10xlarge
+ - m4.16xlarge
+ - m5.large
+ - m5.xlarge
+ - m5.2xlarge
+ - m5.4xlarge
+ - m5.12xlarge
+ - m5.24xlarge
+ - m5d.large
+ - m5d.xlarge
+ - m5d.2xlarge
+ - m5d.4xlarge
+ - m5d.12xlarge
+ - m5d.24xlarge
+ EbsVolumeType:
+ Type: String
+ Description: The value for EBS Volume type in Block Device Mappings for Launch Configuration
+ Default: "gp2"
+ EbsVolumeSize:
+ Type: Number
+ Description: The value for EBS Volume size Block Device Mappings for Launch Configuration
+ Default: "50"
+Resources:
+ ZTSEC2AutoScalingGroup:
+ Type: 'AWS::AutoScaling::AutoScalingGroup'
+ Properties:
+ LaunchConfigurationName: !Ref ZTSLaunchConfig
+ LoadBalancerNames:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-LoadBalancerName"
+ MaxSize: !Ref AutoScalingMaxSize
+ MinSize: !Ref AutoScalingMinSize
+ Cooldown: 300
+ VPCZoneIdentifier:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-PrivateSubnet01ID"
+ - Fn::ImportValue: !Sub "${ResourceStackName}-PrivateSubnet02ID"
+ DesiredCapacity: !Ref AutoScalingDesiredCapacity
+ HealthCheckGracePeriod: 900
+ HealthCheckType: ELB
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-asg-${ServiceName}-${AWS::Region}
+ PropagateAtLaunch: true
+ - Key: Environment
+ Value: !Ref Environment
+ PropagateAtLaunch: true
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PropagateAtLaunch: true
+ ZTSEC2IncreaseGroupSizeScalingPolicy:
+ Type: "AWS::AutoScaling::ScalingPolicy"
+ Properties:
+ AdjustmentType: ChangeInCapacity
+ AutoScalingGroupName: !Ref ZTSEC2AutoScalingGroup
+ Cooldown: 180
+ ScalingAdjustment: 1
+ CPUAlarmHigh:
+ Type: AWS::CloudWatch::Alarm
+ Properties:
+ EvaluationPeriods: '5'
+ Statistic: Average
+ Threshold: '50'
+ Unit: Percent
+ AlarmDescription: Alarm if CPU too high or metric disappears indicating instance
+ is down
+ Period: '60'
+ AlarmActions:
+ - Ref: ZTSEC2IncreaseGroupSizeScalingPolicy
+ Namespace: AWS/EC2
+ Dimensions:
+ - Name: AutoScalingGroupName
+ Value:
+ Ref: ZTSEC2AutoScalingGroup
+ ComparisonOperator: GreaterThanThreshold
+ MetricName: CPUUtilization
+ ZTSEC2DecreaseGroupSizeScalingPolicy:
+ Type: "AWS::AutoScaling::ScalingPolicy"
+ Properties:
+ AdjustmentType: ChangeInCapacity
+ AutoScalingGroupName: !Ref ZTSEC2AutoScalingGroup
+ Cooldown: 300
+ ScalingAdjustment: -1
+ CPUAlarmLow:
+ Type: AWS::CloudWatch::Alarm
+ Properties:
+ EvaluationPeriods: '5'
+ Statistic: Average
+ Threshold: '20'
+ Unit: Percent
+ AlarmDescription: Alarm if CPU too low
+ is down
+ Period: '60'
+ AlarmActions:
+ - Ref: ZTSEC2DecreaseGroupSizeScalingPolicy
+ Namespace: AWS/EC2
+ Dimensions:
+ - Name: AutoScalingGroupName
+ Value:
+ Ref: ZTSEC2AutoScalingGroup
+ ComparisonOperator: LessThanThreshold
+ MetricName: CPUUtilization
+ ZTSLaunchConfig:
+ Type: 'AWS::AutoScaling::LaunchConfiguration'
+ Properties:
+ AssociatePublicIpAddress: false
+ IamInstanceProfile: !Sub arn:aws:iam::${AWS::AccountId}:instance-profile/${ServiceRole}
+ ImageId: !Ref ImageId
+ KeyName: !Ref KeyName
+ InstanceType: !Ref Ec2InstanceType
+ EbsOptimized: !Ref EbsOptimized
+ SecurityGroups:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-ServerSecurityGroupID"
+ BlockDeviceMappings:
+ - DeviceName: "/dev/sda1"
+ Ebs:
+ VolumeSize: !Ref EbsVolumeSize
+ VolumeType: !Ref EbsVolumeType
+ DeleteOnTermination: true
+ InstanceMonitoring: true
\ No newline at end of file
diff --git a/aws-setup/zts-setup/cloud-formation/athens-zts-aws-rds-setup.yaml b/aws-setup/zts-setup/cloud-formation/athens-zts-aws-rds-setup.yaml
new file mode 100644
index 00000000000..f2839a20da0
--- /dev/null
+++ b/aws-setup/zts-setup/cloud-formation/athens-zts-aws-rds-setup.yaml
@@ -0,0 +1,225 @@
+AWSTemplateFormatVersion: 2010-09-09
+Description: 'Athenz ZTS standard 2 Availabilty zone RDS configuration template'
+Parameters:
+ ServiceName:
+ Type: String
+ Description: The service name for ZTS server
+ Default: "zts"
+ GroupName:
+ Type: String
+ Description: The Athens domain for the account
+ Default: "Athenz"
+ ResourceStackName:
+ Type: String
+ Description: Name of Stack used to create AWS Resources
+ Environment:
+ Type: String
+ Description: The environment ZTS is running in
+ AllowedValues:
+ - prod
+ - stage
+ - dev
+ DatabaseName:
+ Type: String
+ Description: Database Name
+ Default: "ztsstore"
+ MinLength: "1"
+ MaxLength: "64"
+ AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
+ ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."
+ DatabaseUsername:
+ NoEcho: "true"
+ Type: String
+ Description: Database Username
+ Default: "dbuser"
+ MinLength: "1"
+ MaxLength: "16"
+ AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
+ ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."
+ DatabasePassword:
+ NoEcho: "true"
+ Type: String
+ Description: Database Password
+ Default: "dbpasswd"
+ MinLength: "1"
+ MaxLength: "41"
+ AllowedPattern: "[a-zA-Z0-9]+"
+ ConstraintDescription: "must contain only alphanumeric characters."
+ DatabaseInstanceClass:
+ Type: String
+ Description: "The database instance type"
+ Default: "db.t2.medium"
+ AllowedValues:
+ - db.t1.micro
+ - db.t1.micro
+ - db.t1.micro
+ - db.t1.micro
+ - db.m1.small
+ - db.m1.medium
+ - db.m1.large
+ - db.m1.xlarge
+ - db.m2.xlarge
+ - db.m2.2xlarge
+ - db.m2.4xlarge
+ - db.m3.medium
+ - db.m3.large
+ - db.m3.xlarge
+ - db.m3.2xlarge
+ - db.m4.large
+ - db.m4.xlarge
+ - db.m4.2xlarge
+ - db.m4.4xlarge
+ - db.m4.10xlarge
+ - db.r3.large
+ - db.r3.xlarge
+ - db.r3.2xlarge
+ - db.r3.4xlarge
+ - db.r3.8xlarge
+ - db.m2.xlarge
+ - db.m2.2xlarge
+ - db.m2.4xlarge
+ - db.cr1.8xlarge
+ - db.t2.micro
+ - db.t2.small
+ - db.t2.medium
+ - db.t2.large"
+ ConstraintDescription: "must select a valid database instance type."
+ EncryptDatabaseStorage:
+ Type: String
+ Description: The Athens domain for the account
+ AllowedValues:
+ - "true"
+ - "false"
+ Default: "true"
+ Route53HostedZoneName:
+ Type: String
+ Description: The hosted zone name to place a CNAME entry for. Must end with a period. Empty string means do not create one.
+ Route53DatabaseRecordName:
+ Type: String
+ Description: The hosted records to be added
+Conditions:
+ CreateDNSRecordSet: !Not [!Equals [ !Ref Route53HostedZoneName, '']]
+ EnableDatabaseEncryption: !Equals [ !Ref EncryptDatabaseStorage , true]
+
+Resources:
+ DatabaseSubnetGroup:
+ Type: AWS::RDS::DBSubnetGroup
+ Properties:
+ DBSubnetGroupDescription: CloudFormation managed DB subnet group.
+ DBSubnetGroupName: !Sub ${Environment}-${ServiceName}-db-subnet
+ SubnetIds:
+ - Fn::ImportValue: !Sub "${ResourceStackName}-PrivateSubnet01ID"
+ - Fn::ImportValue: !Sub "${ResourceStackName}-PrivateSubnet02ID"
+ DatabaseCluster:
+ Type: AWS::RDS::DBCluster
+ Properties:
+ Engine: aurora
+ DatabaseName: !Ref "DatabaseName"
+ MasterUsername: !Ref "DatabaseUsername"
+ MasterUserPassword: !Ref "DatabasePassword"
+ BackupRetentionPeriod: 7
+ PreferredBackupWindow: 01:00-02:00
+ PreferredMaintenanceWindow: mon:03:00-mon:04:00
+ DBSubnetGroupName: !Ref "DatabaseSubnetGroup"
+ VpcSecurityGroupIds: [!Ref "ZTSDBVPCSecurityGroup"]
+ StorageEncrypted: !Ref EncryptDatabaseStorage
+ KmsKeyId: !If [EnableDatabaseEncryption, !GetAtt DatabaseEncryptionKey.Arn, !Ref "AWS::NoValue"]
+ ZTSDBVPCSecurityGroup:
+ Type: "AWS::EC2::SecurityGroup"
+ Properties:
+ GroupName: !Sub ${GroupName}-${Environment}-rds-sg-${ServiceName}-${AWS::Region}
+ GroupDescription: 'ZTS public db security group'
+ SecurityGroupIngress:
+ - IpProtocol: TCP
+ FromPort: '3306'
+ ToPort: '3306'
+ CidrIp: '10.0.0.0/20'
+ VpcId:
+ Fn::ImportValue: !Sub "${ResourceStackName}-VPCID"
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-rds-sg-${ServiceName}-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ DatabaseEncryptionKey:
+ Type: 'AWS::KMS::Key'
+ Condition: EnableDatabaseEncryption
+ Properties:
+ Description: "KMS key for database encryption"
+ EnableKeyRotation: true
+ Enabled: true
+ KeyPolicy:
+ Version: 2012-10-17
+ Id: key-default-1
+ Statement:
+ - Sid: Enable IAM User Permissions
+ Effect: Allow
+ Principal:
+ AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
+ Action: 'kms:*'
+ Resource: '*'
+ Tags:
+ - Key: Name
+ Value: !Sub ${DatabaseName}-${AWS::Region}-encryption-key
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ DatabaseEncryptionKeyAlias:
+ Type: AWS::KMS::Alias
+ Condition: EnableDatabaseEncryption
+ Properties:
+ AliasName: !Sub alias/${DatabaseName}-${AWS::Region}-encryption-key
+ TargetKeyId: !Ref DatabaseEncryptionKey
+ DatabasePrimaryInstance:
+ Type: AWS::RDS::DBInstance
+ Properties:
+ Engine: aurora
+ DBClusterIdentifier: !Ref "DatabaseCluster"
+ DBInstanceClass: !Ref DatabaseInstanceClass
+ DBSubnetGroupName: !Ref "DatabaseSubnetGroup"
+ PubliclyAccessible: "false"
+ DBInstanceIdentifier: !Ref "DatabaseName"
+ Tags:
+ - Key: Name
+ Value: !Ref "DatabaseName"
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ DatabaseReplicaInstance:
+ Type: AWS::RDS::DBInstance
+ Properties:
+ Engine: aurora
+ DBClusterIdentifier: !Ref "DatabaseCluster"
+ DBInstanceClass: !Ref DatabaseInstanceClass
+ DBSubnetGroupName: !Ref "DatabaseSubnetGroup"
+ PubliclyAccessible: "false"
+ DBInstanceIdentifier: !Sub ${DatabaseName}-${AWS::Region}
+ Tags:
+ - Key: Name
+ Value: !Sub ${DatabaseName}-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ ZTSDatabaseRecordSet:
+ Type: AWS::Route53::RecordSet
+ Condition: CreateDNSRecordSet
+ Properties:
+ Comment: CNAME record for the ZTS DB.
+ HostedZoneName: !Ref Route53HostedZoneName
+ Name: !Ref Route53DatabaseRecordName
+ TTL: 60
+ Type: CNAME
+ ResourceRecords:
+ - !GetAtt DatabaseCluster.Endpoint.Address
+Outputs:
+ DatabasePrimaryInstanceEndpoint:
+ Description: Endpoint for primary database
+ Value: !GetAtt DatabasePrimaryInstance.Endpoint.Address
+ DatabaseReplicaInstanceEndpoint:
+ Description: Endpoint for primary database
+ Value: !GetAtt DatabaseReplicaInstance.Endpoint.Address
\ No newline at end of file
diff --git a/aws-setup/zts-setup/cloud-formation/athens-zts-aws-resource-setup.yaml b/aws-setup/zts-setup/cloud-formation/athens-zts-aws-resource-setup.yaml
new file mode 100644
index 00000000000..146c0bd818d
--- /dev/null
+++ b/aws-setup/zts-setup/cloud-formation/athens-zts-aws-resource-setup.yaml
@@ -0,0 +1,813 @@
+AWSTemplateFormatVersion: 2010-09-09
+Description: 'Athenz ZTS standard 2 Availabilty zone configuration template'
+Parameters:
+ ZTSServiceName:
+ Type: String
+ Description: The service name for ZTS server
+ Default: "zts"
+ ZTSVPCCidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the ZTS VPC.
+ Default: "10.0.0.0/18"
+ PrivateSubnet01CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Private Subnet Zone 1.
+ Default: "10.0.0.0/22"
+ PrivateSubnet02CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Private Subnet Zone 2.
+ Default: "10.0.4.0/22"
+ PublicSubnet01CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Public Subnet Zone 1.
+ Default: "10.0.8.0/22"
+ PublicSubnet02CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Public Subnet Zone 2.
+ Default: "10.0.12.0/22"
+ CertSignerPrivateSubnet01CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Cert Signer Private Subnet Zone 1.
+ Default: "10.0.16.0/22"
+ CertSignerPrivateSubnet02CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Cert Signer Private Subnet Zone 2.
+ Default: "10.0.20.0/22"
+ CertSignerPublicSubnet01CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Cert Signer Public Subnet Zone 1.
+ Default: "10.0.26.0/23"
+ CertSignerPublicSubnet02CidrBlock:
+ AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
+ ConstraintDescription: "must be an IP address block in Cidr notation."
+ MaxLength: "18"
+ MinLength: "9"
+ Type: String
+ Description: The CIDR block to use for the Cert Signer Public Subnet Zone 2.
+ Default: "10.0.30.0/23"
+ GroupName:
+ Type: String
+ Description: The Athens domain for the account
+ Default: "Athenz"
+ Environment:
+ Type: String
+ Description: The environment ZTS is running in
+ AllowedValues:
+ - prod
+ - stage
+ - dev
+ S3AccessLogBucketName:
+ Type: String
+ Description: S3 bucket name to store access logs
+ Route53HostedZoneName:
+ Type: String
+ Description: The hosted zone name to place a CNAME entry for. Must end with a period. Empty string means do not create one.
+ Route53RecordName:
+ Type: String
+ Description: The hosted records to be added
+Conditions:
+ CreateDNSRecordSet: !Not [!Equals [ !Ref Route53HostedZoneName, '']]
+Resources:
+ ZTSVPC:
+ Type: 'AWS::EC2::VPC'
+ Properties:
+ CidrBlock: !Ref 'ZTSVPCCidrBlock'
+ EnableDnsSupport: true
+ EnableDnsHostnames: true
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet01:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PrivateSubnet01CidrBlock'
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}-${AWS::Region}a-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet02:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 1
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PrivateSubnet02CidrBlock'
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}-${AWS::Region}b-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet01:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PublicSubnet01CidrBlock'
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}-${AWS::Region}a-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet02:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 1
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'PublicSubnet02CidrBlock'
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}-${AWS::Region}b-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ CertSignerPrivateSubnet01:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'CertSignerPrivateSubnet01CidrBlock'
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-certsignd-${AWS::Region}a-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ CertSignerPrivateSubnet02:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 1
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'CertSignerPrivateSubnet02CidrBlock'
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-certsignd-${AWS::Region}b-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ CertSignerPublicSubnet01:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'CertSignerPublicSubnet01CidrBlock'
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-certsignd-${AWS::Region}a-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ CertSignerPublicSubnet02:
+ Type: 'AWS::EC2::Subnet'
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 1
+ - Fn::GetAZs: ""
+ CidrBlock: !Ref 'CertSignerPublicSubnet02CidrBlock'
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-certsignd-${AWS::Region}b-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ Nacl:
+ Type: "AWS::EC2::NetworkAcl"
+ Properties:
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ NetworkAclEntry01:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '100'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: !Ref 'ZTSVPCCidrBlock'
+ PortRange:
+ From: '22'
+ To: '22'
+ NetworkAclEntry02:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '110'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '4443'
+ To: '4443'
+ NetworkAclEntry03:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '120'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '8443'
+ To: '8443'
+ NetworkAclEntry04:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '130'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '3306'
+ To: '3306'
+ NetworkAclEntry05:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '140'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '80'
+ To: '80'
+ NetworkAclEntry06:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '150'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '443'
+ To: '443'
+ NetworkAclEntry07:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '160'
+ Protocol: "17"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '123'
+ To: '123'
+ NetworkAclEntry08:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ Egress: 'true'
+ RuleNumber: '200'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '1024'
+ To: '65535'
+ NetworkAclEntry09:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '100'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '22'
+ To: '22'
+ NetworkAclEntry10:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '110'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '4443'
+ To: '4443'
+ NetworkAclEntry11:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '120'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '8443'
+ To: '8443'
+ NetworkAclEntry12:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '130'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '3306'
+ To: '3306'
+ NetworkAclEntry13:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '140'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '80'
+ To: '80'
+ NetworkAclEntry14:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '150'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '443'
+ To: '443'
+ NetworkAclEntry15:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '160'
+ Protocol: "17"
+ RuleAction: allow
+ CidrBlock: !Ref 'ZTSVPCCidrBlock'
+ PortRange:
+ From: '123'
+ To: '123'
+ NetworkAclEntry16:
+ Type: AWS::EC2::NetworkAclEntry
+ Properties:
+ NetworkAclId: !Ref 'Nacl'
+ RuleNumber: '200'
+ Protocol: "6"
+ RuleAction: allow
+ CidrBlock: 0.0.0.0/0
+ PortRange:
+ From: '1024'
+ To: '65535'
+ PrivateSubnet01Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PrivateSubnet01'
+ NetworkAclId: !Ref 'Nacl'
+ PrivateSubnet02Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PrivateSubnet02'
+ NetworkAclId: !Ref 'Nacl'
+ PublicSubnet01Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PublicSubnet01'
+ NetworkAclId: !Ref 'Nacl'
+ PublicSubnet02Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'PublicSubnet02'
+ NetworkAclId: !Ref 'Nacl'
+ CertSignerPrivateSubnet01Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'CertSignerPrivateSubnet01'
+ NetworkAclId: !Ref 'Nacl'
+ CertSignerPrivateSubnet02Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'CertSignerPrivateSubnet02'
+ NetworkAclId: !Ref 'Nacl'
+ CertSignerPublicSubnet01Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'CertSignerPublicSubnet01'
+ NetworkAclId: !Ref 'Nacl'
+ CertSignerPublicSubnet02Nacl:
+ Type: "AWS::EC2::SubnetNetworkAclAssociation"
+ Properties:
+ SubnetId: !Ref 'CertSignerPublicSubnet02'
+ NetworkAclId: !Ref 'Nacl'
+ InternetGateway:
+ Type: "AWS::EC2::InternetGateway"
+ Properties:
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ VPCGatewayAttachment:
+ Type: "AWS::EC2::VPCGatewayAttachment"
+ Properties:
+ InternetGatewayId: !Ref 'InternetGateway'
+ VpcId: !Ref 'ZTSVPC'
+ PublicSubnet01NatGateway:
+ Type: "AWS::EC2::NatGateway"
+ Properties:
+ AllocationId: !GetAtt PublicSubnet01EIP.AllocationId
+ SubnetId: !Ref 'PublicSubnet01'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}-${AWS::Region}a
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet01EIP:
+ DependsOn: VPCGatewayAttachment
+ Type: AWS::EC2::EIP
+ Properties:
+ Domain: vpc
+ PublicSubnet02NatGateway:
+ Type: "AWS::EC2::NatGateway"
+ Properties:
+ AllocationId: !GetAtt PublicSubnet02EIP.AllocationId
+ SubnetId: !Ref 'PublicSubnet02'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}-${AWS::Region}b
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PublicSubnet02EIP:
+ DependsOn: VPCGatewayAttachment
+ Type: AWS::EC2::EIP
+ Properties:
+ Domain: vpc
+ CertSignerPublicSubnet01NatGateway:
+ Type: "AWS::EC2::NatGateway"
+ Properties:
+ AllocationId: !GetAtt CertSignerPublicSubnet01EIP.AllocationId
+ SubnetId: !Ref 'CertSignerPublicSubnet01'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-certsignd-${AWS::Region}a
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ CertSignerPublicSubnet01EIP:
+ DependsOn: VPCGatewayAttachment
+ Type: AWS::EC2::EIP
+ Properties:
+ Domain: vpc
+ CertSignerPublicSubnet02NatGateway:
+ Type: "AWS::EC2::NatGateway"
+ Properties:
+ AllocationId: !GetAtt CertSignerPublicSubnet02EIP.AllocationId
+ SubnetId: !Ref 'CertSignerPublicSubnet02'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-certsignd-${AWS::Region}b
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ CertSignerPublicSubnet02EIP:
+ DependsOn: VPCGatewayAttachment
+ Type: AWS::EC2::EIP
+ Properties:
+ Domain: vpc
+ PublicSubnetRouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}-${AWS::Region}-public
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ GatewayRoute:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ GatewayId: !Ref 'InternetGateway'
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ DependsOn: VPCGatewayAttachment
+ PrivateSubnet01RouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}-${AWS::Region}a-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet01Route:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ NatGatewayId: !Ref 'PublicSubnet01NatGateway'
+ RouteTableId: !Ref 'PrivateSubnet01RouteTable'
+ PrivateSubnet02RouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-${ZTSServiceName}-${AWS::Region}b-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ PrivateSubnet02Route:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ NatGatewayId: !Ref 'PublicSubnet02NatGateway'
+ RouteTableId: !Ref 'PrivateSubnet02RouteTable'
+ DependsOn: VPCGatewayAttachment
+ CertSignerPrivateSubnet01RouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-certsignd-${AWS::Region}a-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ CertSignerPrivateSubnet01Route:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ NatGatewayId: !Ref 'CertSignerPublicSubnet01NatGateway'
+ RouteTableId: !Ref 'CertSignerPrivateSubnet01RouteTable'
+ CertSignerPrivateSubnet02RouteTable:
+ Type: "AWS::EC2::RouteTable"
+ Properties:
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-certsignd-${AWS::Region}b-private
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ CertSignerPrivateSubnet02Route:
+ Type: "AWS::EC2::Route"
+ Properties:
+ DestinationCidrBlock: '0.0.0.0/0'
+ NatGatewayId: !Ref 'CertSignerPublicSubnet02NatGateway'
+ RouteTableId: !Ref 'CertSignerPrivateSubnet02RouteTable'
+ DependsOn: VPCGatewayAttachment
+ PublicSubnet01RouteTableAssociaton:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ SubnetId: !Ref 'PublicSubnet01'
+ PublicSubnet02RouteTableAssociaton:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ SubnetId: !Ref 'PublicSubnet02'
+ CertSignerPublicSubnet01RouteTableAssociaton:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ SubnetId: !Ref 'CertSignerPublicSubnet01'
+ CertSignerPublicSubnet02RouteTableAssociaton:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PublicSubnetRouteTable'
+ SubnetId: !Ref 'CertSignerPublicSubnet02'
+ PrivateSubnet01RouteTableAssociation:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PrivateSubnet01RouteTable'
+ SubnetId: !Ref 'PrivateSubnet01'
+ PrivateSubnet02RouteTableAssociation:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'PrivateSubnet02RouteTable'
+ SubnetId: !Ref 'PrivateSubnet02'
+ CertSignerPrivateSubnet01RouteTableAssociation:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'CertSignerPrivateSubnet01RouteTable'
+ SubnetId: !Ref 'CertSignerPrivateSubnet01'
+ CertSignerPrivateSubnet02RouteTableAssociation:
+ Type: "AWS::EC2::SubnetRouteTableAssociation"
+ Properties:
+ RouteTableId: !Ref 'CertSignerPrivateSubnet02RouteTable'
+ SubnetId: !Ref 'CertSignerPrivateSubnet02'
+ ZTSELBSecurityGroup:
+ Type: "AWS::EC2::SecurityGroup"
+ Properties:
+ GroupName: !Sub ${GroupName}-${Environment}-elb-sg-${ZTSServiceName}-${AWS::Region}
+ GroupDescription: 'ZTS public elb security group'
+ SecurityGroupIngress:
+ - IpProtocol: tcp
+ FromPort: '4443'
+ ToPort: '4443'
+ CidrIp: '0.0.0.0/0'
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-elb-${ZTSServiceName}-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ ZTSServerSecurityGroup:
+ Type: "AWS::EC2::SecurityGroup"
+ Properties:
+ GroupName: !Sub ${GroupName}-${Environment}-server-sg-${ZTSServiceName}-${AWS::Region}
+ GroupDescription: 'ZTS public server security group'
+ SecurityGroupIngress:
+ - IpProtocol: tcp
+ FromPort: '4443'
+ ToPort: '4443'
+ CidrIp: '0.0.0.0/0'
+ - IpProtocol: tcp
+ FromPort: '8443'
+ ToPort: '8443'
+ CidrIp: !Ref 'ZTSVPCCidrBlock'
+ VpcId: !Ref 'ZTSVPC'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-server-${ZTSServiceName}-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ ZTSLoadBalancer:
+ Type: "AWS::ElasticLoadBalancing::LoadBalancer"
+ Properties:
+ HealthCheck:
+ HealthyThreshold: 2
+ Interval: 10
+ Target: !Sub HTTPS:8443/${ZTSServiceName}/v1/status
+ Timeout: 5
+ UnhealthyThreshold: 2
+ Listeners:
+ - InstancePort: 4443
+ InstanceProtocol: TCP
+ LoadBalancerPort: 4443
+ Protocol: TCP
+ Policies:
+ - PolicyName: "EnableProxyProtocol"
+ PolicyType: "ProxyProtocolPolicyType"
+ Attributes:
+ - Name: ProxyProtocol
+ Value: 'true'
+ InstancePorts:
+ - '4443'
+ LoadBalancerName: !Sub ${Environment}-elb-${ZTSServiceName}-${AWS::Region}
+ Scheme: 'internet-facing'
+ ConnectionDrainingPolicy:
+ Enabled: 'true'
+ Timeout: '60'
+ CrossZone: true
+ SecurityGroups:
+ - !Ref ZTSELBSecurityGroup
+ Subnets:
+ - !Ref 'PublicSubnet01'
+ - !Ref 'PublicSubnet02'
+ AccessLoggingPolicy:
+ S3BucketName: !Ref S3AccessLogBucketName
+ S3BucketPrefix: !Sub elb-${ZTSServiceName}
+ Enabled: 'true'
+ EmitInterval: '60'
+ Tags:
+ - Key: Name
+ Value: !Sub ${Environment}-elb-ZTS-${AWS::Region}
+ - Key: Environment
+ Value: !Ref Environment
+ - Key: Stack
+ Value: !Ref AWS::StackName
+ ZTSRecordSet:
+ Type: AWS::Route53::RecordSet
+ Condition: CreateDNSRecordSet
+ Properties:
+ Comment: CNAME record for the ZTS Server.
+ HostedZoneName: !Ref Route53HostedZoneName
+ Name: !Ref Route53RecordName
+ TTL: 60
+ Type: CNAME
+ ResourceRecords:
+ - !GetAtt ZTSLoadBalancer.DNSName
+Outputs:
+ ZTSVPCID:
+ Description: The ID of the ZTS VPC
+ Value: !Ref ZTSVPC
+ Export:
+ Name: !Sub "${AWS::StackName}-VPCID"
+ PrivateSubnet01ID:
+ Description: The ID of Private Subnet Availability Zone 1 in ZTS VPC
+ Value: !Ref PrivateSubnet01
+ Export:
+ Name: !Sub "${AWS::StackName}-PrivateSubnet01ID"
+ PrivateSubnet02ID:
+ Description: The ID of Private Subnet Availability Zone 2 in ZTS VPC
+ Value: !Ref PrivateSubnet02
+ Export:
+ Name: !Sub "${AWS::StackName}-PrivateSubnet02ID"
+ LoadBalancerName :
+ Description: The name of ZTS Load Balancer
+ Value: !Ref ZTSLoadBalancer
+ Export:
+ Name: !Sub "${AWS::StackName}-LoadBalancerName"
+ ServerSecurityGroupID:
+ Description: The ID of ZTS Server security group
+ Value: !Ref ZTSServerSecurityGroup
+ Export:
+ Name: !Sub "${AWS::StackName}-ServerSecurityGroupID"
+
+
\ No newline at end of file
diff --git a/aws-setup/zts-setup/cloud-formation/athens-zts-aws-roles-setup.yaml b/aws-setup/zts-setup/cloud-formation/athens-zts-aws-roles-setup.yaml
new file mode 100644
index 00000000000..6a9ffff64cb
--- /dev/null
+++ b/aws-setup/zts-setup/cloud-formation/athens-zts-aws-roles-setup.yaml
@@ -0,0 +1,52 @@
+AWSTemplateFormatVersion: 2010-09-09
+Description: Roles needed for athens zts setup
+Parameters:
+ AthensServiceRole:
+ Type: String
+ Description: The Athens role name for the service
+ Default: athenz.zts-service
+Resources:
+ AthensServiceEC2Role:
+ Type: "AWS::IAM::Role"
+ Properties:
+ AssumeRolePolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ -
+ Effect: "Allow"
+ Principal:
+ Service:
+ - "ec2.amazonaws.com"
+ Action:
+ - "sts:AssumeRole"
+ Policies:
+ -
+ PolicyName: !Sub ${AthensServiceRole}.policy
+ PolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ - Effect: "Allow"
+ Action:
+ - logs:CreateLogGroup
+ - logs:CreateLogStream
+ - logs:PutLogEvents
+ - logs:DescribeLogStreams
+ - logs:DescribeLogGroups
+ Resource: "arn:aws:logs:*:*:*"
+ - Effect: "Allow"
+ Action:
+ - rds-db:connect
+ Resource:
+ - !Sub arn:aws:rds-db:us-west-2:${AWS::AccountId}:dbuser:*/zts
+ - !Sub arn:aws:rds-db:us-east-1:${AWS::AccountId}:dbuser:*/zts
+ - Effect: "Allow"
+ Action: "ec2:DescribeTags"
+ Resource: "*"
+ Path: /
+ RoleName: !Ref AthensServiceRole
+ AthensEc2InstanceProfile:
+ Type: "AWS::IAM::InstanceProfile"
+ Properties:
+ Roles:
+ - !Ref AthensServiceEC2Role
+ InstanceProfileName: !Ref AthensServiceRole
\ No newline at end of file
diff --git a/aws-setup/zts-setup/packer/aws/packer.json b/aws-setup/zts-setup/packer/aws/packer.json
new file mode 100755
index 00000000000..cc5b4de4c33
--- /dev/null
+++ b/aws-setup/zts-setup/packer/aws/packer.json
@@ -0,0 +1,106 @@
+{
+ "variables": {
+ "subnet_id":"subnet-xxxxxxxxx",
+ "vpc_id": "vpc-xxxxxxxxxxxxxx",
+ "aws_region": "{{env `AWS_REGION`}}",
+ "aws_ami_name": "zts-aws-cd-image",
+ "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
+ "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}",
+ "aws_session_token": "{{env `AWS_SESSION_TOKEN`}}",
+ "ssh_keypair_name":"keypair-name",
+ "ssh_private_key_file":"path to ssh key file",
+ "source_ami": "ami-02c71d7a"
+ },
+ "builders": [
+ {
+ "access_key": "{{user `aws_access_key`}}",
+ "secret_key": "{{user `aws_secret_key`}}",
+ "token": "{{user `aws_session_token`}}",
+ "name": "amazon-ebs",
+ "ssh_username": "centos",
+ "ssh_keypair_name":"{{user `ssh_keypair_name`}}",
+ "ssh_private_key_file":"{{user `ssh_private_key_file`}}",
+ "type": "amazon-ebs",
+ "region": "{{user `aws_region`}}",
+ "source_ami": "{{user `source_ami`}}",
+ "ami_block_device_mappings": [
+ {
+ "device_name": "/dev/sda1",
+ "volume_type": "gp2",
+ "volume_size": 50,
+ "encrypted": true,
+ "delete_on_termination": true
+ }
+ ],
+ "encrypt_boot": true,
+ "instance_type": "t2.micro",
+ "ami_name": "{{user `aws_ami_name`}}",
+ "ami_description": "ZMS Image for cloud formation",
+ "associate_public_ip_address": "true",
+ "subnet_id": "{{ user `subnet_id` }}",
+ "vpc_id": "{{ user `vpc_id` }}"
+ }],
+
+ "provisioners": [
+ {
+ "type": "shell",
+ "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
+ "inline": [
+ "mkdir -p /opt",
+ "chmod a+w /opt"
+ ]
+ },
+ {
+ "type": "shell",
+ "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
+ "inline": [
+ "mkdir -p /opt/zts/tars",
+ "mkdir -p /opt/zts/jars",
+ "mkdir -p /opt/zts/logs",
+ "mkdir -p /opt/zts/domains",
+ "mkdir -p /opt/zts/webapps",
+ "mkdir -p /opt/zts/etc",
+ "mkdir -p /opt/zts/bin",
+ "mkdir -p /opt/zts/temp",
+ "mkdir -p /opt/zts/service",
+ "mkdir -p /opt/zts/conf",
+ "mkdir /var/log/zts_server",
+ "chmod 777 /opt/zts -R"
+ ]
+ },
+ {
+ "type": "file",
+ "source": "build/bin/",
+ "destination": "/opt/zts/bin/"
+ },
+ {
+ "type": "file",
+ "source": "build/conf/",
+ "destination": "/opt/zts/conf/"
+ },
+ {
+ "type": "file",
+ "source": "build/service/",
+ "destination": "/opt/zts/service"
+ },
+ {
+ "type": "file",
+ "source": "tars/",
+ "destination": "/opt/zts/tars/"
+ },
+ {
+ "type": "shell",
+ "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
+ "inline": [
+ "ls -ltr /opt/"
+ ]
+ },
+ {
+ "type": "shell",
+ "scripts": [
+ "packer/scripts/setup.sh"
+ ],
+ "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E '{{ .Path }}'"
+ }
+ ]
+}
diff --git a/aws-setup/zts-setup/packer/scripts/setup.sh b/aws-setup/zts-setup/packer/scripts/setup.sh
new file mode 100755
index 00000000000..5f1747f93ec
--- /dev/null
+++ b/aws-setup/zts-setup/packer/scripts/setup.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env bash
+set -xe
+
+# install epel
+
+sudo yum -y install epel-release
+sudo yum repolist
+
+# install aws_cli
+
+echo "install aws"
+sudo yum -y install python-pip
+sudo pip install awscli
+aws --version
+
+# install openjdk
+
+sudo yum -y install java-1.8.0-openjdk
+
+# setup our athenz group and user
+
+sudo groupadd athenz
+sudo useradd -g athenz athenz-zts
+
+
+# Copying jars, war and webdefault.xml files
+sudo tar -xzf /opt/zts/tars/athenz-zts-bin.tar.gz -C /opt/zts/tars/
+sudo ls -ltr /opt/zts/tars/
+sudo cp -r /opt/zts/tars/athenz-zts/lib/jars/ /opt/zts/
+sudo cp /opt/zts/tars/athenz-zts/etc/webdefault.xml /opt/zts/etc/
+sudo cp /opt/zts/tars/athenz-zts/webapps/zts.war /opt/zts/webapps/
+sudo cp -r /opt/zts/tars/athenz-zts/bin/linux/ /opt/zts/bin/
+
+# setup our zts service
+
+sudo mkdir /etc/zts
+sudo cp /opt/zts/service/zts.service /etc/zts/zts.service
+sudo systemctl enable /etc/zts/zts.service
+sudo cp /opt/zts/conf/zts-user /etc/sudoers.d/
+
+#set up aws logs
+
+curl https://s3.amazonaws.com//aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -o /opt/zts/logs/awslogs-agent-setup.py
+
+# make sure all files are owned by our user/group
+
+sudo chown -R athenz-zts:athenz /opt/zts
diff --git a/docs/aws_athenz_setup.md b/docs/aws_athenz_setup.md
new file mode 100644
index 00000000000..0b0c67d1ee2
--- /dev/null
+++ b/docs/aws_athenz_setup.md
@@ -0,0 +1,30 @@
+# Athenz Setup on AWS
+------------------
+- [Build the project](##-build-the-projet)
+- [ZMS Setup](##-zms-setup)
+- [ZTS Setup](##-zms-setup)
+- [ZMS Setup](##-zms-setup)
+
+## Build the Project
+-----------------
+`mvn clean install`
+
+Make sure to have the following tar files:
+
+```
+aws-setup/zms-setup/tars/athenz-zms-bin.tar.gz
+aws-setup/zts-setup/tars/athenz-zts-bin.tar.gz
+aws-setup/ui-setup/tars/athenz-ui-bin.tar.gz
+```
+
+## ZMS Setup
+
+Refer [AWS ZMS Setup](aws_zms_setup.md) for details
+
+## ZTS Setup
+
+Refer [AWS ZTS Setup](aws_zts_setup.md) for details
+
+## UI Setup
+
+Refer [AWS UI Setup](aws_ui_setup.md) for details
diff --git a/docs/aws_ui_setup.md b/docs/aws_ui_setup.md
new file mode 100644
index 00000000000..276bf6c7607
--- /dev/null
+++ b/docs/aws_ui_setup.md
@@ -0,0 +1,185 @@
+# Setup UI on AWS
+-------------------
+- [AWS Resource Setup](###-aws-resource-setup)
+ - [IAM role setup](####-iam-role-setup)
+ - [VPC setup](####-vpc-setup)
+ - [S3 bucket for UI data](####-create-s3-bucket-to-store-ui-data)
+ - [Generate and upload service private key](#####-generate-and-upload-service-private-key)
+ - [Upload server X.509 cert and key](#####-upload-server-x.509-cert-and-key)
+ - [Upload ZMS CA Certs](#####-upload-zms-ca-certs)
+ - [Upload ZMS Public key](#####-upload-zms-public-key)
+ - [Update ZMS DATA BUCKET](####-update-zms-data-bucket)
+ - [Register UI Service](####-register-ui-service)
+ - [Packer](####-packer)
+ - [Packer VPC setup](#####-packer-vpc-setup)
+ - [Build UI Image](#####-build-ui-image)
+ - [Deploy UI](####deploy-ui)
+
+## AWS Resource Setup
+-------------
+
+### IAM role setup
+--
+Create EC2 profile role for UI using cloudformation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/ui-setup/cloud-formation/athens-ui-aws-roles-setup.yaml). This template creates a role named `athenz.ui-service`
+
+### VPC Setup
+--
+Setup VPC using the cloudformation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/ui-setup/cloud-formation/athens-ui-aws-resource-setup.yaml) and giving the following mandatory parameters
+- `Route53HostedZoneName`
+- `Route53RecordName`
+- `S3AccessLogBucketName`(Created during Zms Setup)
+- `Environment`
+
+The other parameters are set by default. Change them as per your requirement
+
+*NOTE - Modifying the other defaults might require subsequent changes.*
+
+Following resources will be created after executing the template
+1. 2 availability zones
+1. Public & Private subnets for ui in each availability zone
+1. 2 NAT gateways and elastic IPs
+1. NACL's for the subnets
+1. Internet gateways for all public subnets
+1. Route tables for all subnets
+1. Elastic load balancer
+1. Route 53 DNS entry
+1. UI server & ELB security groups
+
+
+### Create S3 bucket to store UI data
+--------------------------------------
+
+Create S3 bucket for storing ui certificates & keys with appropriate policy as follows
+```
+{
+"Version": "2012-10-17",
+"Statement": [
+ {
+ "Sid": "",
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": "arn:aws:iam:::role/athenz.ui-service"
+ },
+ "Action": "s3:GetObject",
+ "Resource": "arn:aws:s3::: /*"
+ }
+ ]
+}
+```
+Also enable Default Encryption for your bucket.
+
+*NOTE - athenz.ui-service is the EC2 role created using IAM template above*
+
+#### Generate and upload service private key
+--
+Generate a unique private key that UI Server will use to sign user's authorized service tokens.
+The UI has already been authorized to be allowed to carry out the users' requested operations.
+```
+openssl genrsa -out service_private_key 2048
+openssl rsa -in service_private_key -pubout > ui_service_x509_key_public
+```
+Upload the service private key with name `service_private_key` onto the s3 bucket
+
+#### Upload server X.509 cert and key
+--
+NOTE - For Athenz UI production server it is strongly recommended to purchase a
+certificate for HTTPS access from a well known certificate authority.
+Follow the instructions provided by the Certificate Authority to generate your private key
+and then the Certificate Request (CSR).
+
+However if you want to use the self signed certificate, you can generate a self signed certificate
+as below
+
+ ```
+ openssl req -newkey rsa:2048 -nodes -keyout service_x509_key -x509 -days 365 -out service_x509_cer
+ ```
+- Verify your certs
+ ```
+ openssl x509 -in service_x509_cert -text -noout
+ ```
+- Once you have received your X509 certificate and key,
+ - Upload the certificate on s3 bucket with name `service_x509_cert`
+ - Upload the private key with name `service_x509_key`
+
+#### Upload ZMS CA Certs
+
+- Upload ZMS CA Cert with key `zms_service_x509_ca_certs`. They will be needed so that UI can communicate securely with ZMS
+
+#### Upload ZMS Public keys
+
+- Upload ZMS public key with name `zms_service_x509_key_public.pem `
+
+It is required to generate athenz.conf file at `/opt/athenz-ui/conf/athenz.conf` to include the ZMS Server URL and the registered public keys that the athenz
+client libraries and utilities will use to establish connection and validate any data signed by the ZMS Server:
+
+### Update ZMS DATA BUCKET
+
+- Upload UI service public key to ZMS Data Bucket with key `ui_service_x509_key_public.pem`
+
+### Register UI Service
+In order for UI to access ZMS domain data, it must identify itself
+as a registered service in ZMS. Use `zms-cli` utility to
+register a new service in `athenz` domain. If ZMS Servers are
+running with a X509 certificate from a well know certificate
+authority (not a self-signed one) we don't need to reference the CA
+cert like we are doing below for self signed certs.
+
+Login into your zms-server instance as domain admin you created during zms setup and run the below commands:
+
+```
+- Download ZMS CA Certs(If using self signed certs)
+ aws s3 cp s3:///zms_service_x509_ca_certs /tmp/zms_service_x509_ca_certs
+- Download UI public key
+ aws s3 cp s3:// /ui_service_x509_key_public.pem/tmp/ui_service_x509_key_public.pem
+- Add a new domain named `athenz`
+ /opt/zms/bin/zms-cli -c /tmp/service_x509_ca_certs -z -add-domain athenz
+- Register Service using zms-cli
+ /opt/zms/bin/zms-cli -c /tmp/service_x509_ca_certs -z -d athenz add-service ui 0 /tmp/ui_service_x509_key_public.pem
+```
+*NOTE - Append /zms/v1 to your url in the command above*
+
+For e.g. If your zms server is running at https://athenz.zms.com:4443 then pass `https://athenz.zms.com:4443/zms/v1`.
+
+### Packer
+--
+#### Packer VPC Setup
+
+Packer VPC was set during zms setup, update `packer.json` accordingly.
+```
+{
+ "subnet_id":"",
+ "vpc_id": "",
+ "aws_region": "",
+ "aws_ami_name": "ui-aws-cd-image",
+ "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
+ "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}",
+ "aws_session_token": "{{env `AWS_SESSION_TOKEN`}}",
+ "ssh_keypair_name":"",
+ "ssh_private_key_file":"",
+ "source_ami": "ami-02c71d7a"
+}
+```
+
+#### Build UI image
+--
+Build the image with packer using the following command
+
+```
+cd /aws-setup/ui-setup
+packer build packer/aws/packer.json
+```
+
+### Deploy UI
+--
+Run cloud formation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/ui-setup/cloud-formation/athenz-ui-aws-instance-deployment.yaml) to bring up the ui-instances in 2 availability zones.
+- The imageID parameter should be set to the image created in above step.
+
+The UI Server is now up and running.
+
+*NOTE - If using self-signed X509 certificates for Athenz ZMS and UI servers, the administrator
+must add exceptions when accessing Athenz UI or install the self-signed certificates for those
+two servers into his/her own web browser. The administrator must first access the ZMS Server
+endpoint in the browser to accept the exception since the Athenz UI contacts ZMS Server to get
+an authorized token for the user when logging in.
+Alternatively, the administrator may decide to install the self-signed certificates for the ZMS and UI servers in their browser.*
+
diff --git a/docs/aws_zms_setup.md b/docs/aws_zms_setup.md
new file mode 100644
index 00000000000..1009f4dd425
--- /dev/null
+++ b/docs/aws_zms_setup.md
@@ -0,0 +1,331 @@
+# Setup ZMS on AWS
+-------------------
+- [AWS Resource Setup](###-aws-resource-setup)
+ - [IAM role setup](####-iam-role-setup)
+ - [S3 bucket for ELB logs](####-s3-bucket-for-elb-logs)
+ - [VPC setup](####-vpc-setup)
+ - [RDS Setup](####-rds-setup)
+ - [Create Aurora Mysql cluster](#####-create-an-aurora-mysql-cluster)
+ - [Schema setup](#####-set-up-the-schema)
+ - [S3 bucket to store zms data](####-create-s3-bucket-to-store-zms-data)
+ - [Generate and upload service private key](#####-generate-and-upload-service-private-key-and-id)
+ - [Upload server X.509 cert and key](#####-upload-server-x.509-cert-and-key)
+ - [Upload RDS CA Certs](#####-upload-rds-ca-certs)
+ - [Upload truststore password](#####-upload-truststore-password)
+ - [Upload ZMS DB User Password](#####-upload-zms-db-user-password)
+ - [Create S3 Bucket for Audit logs](####-create-s3-bucket-for-audit-logs)
+ - [Edit Variables & Properties](####-edit-variables-&-properties)
+ - [aws_init.sh](#####-edit-aws_init.sh)
+ - [zms.properties](#####-edit-the-zms.properties-file)
+ - [Database Access](######-database-access)
+ - [User Authentication](######-user-authentication)
+ - [Domain Admins](######-domain-admins)
+ - [athenz.properties](#####-edit-athenz.properties-file)
+ - [Truststore and Keystore Settings](#####-truststore-and-keystore-settings)
+ - [Packer](####-packer)
+ - [Packer VPC setup](#####-packer-vpc-setup)
+ - [Build ZMS Image](#####-build-zms-image)
+ - [Deploy ZMS](####deploy-zms)
+
+## AWS Resource Setup
+-------------
+
+### IAM role setup
+--
+Create EC2 profile role for zms using cloudformation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/zms-setup/cloud-formation/athens-zms-aws-roles-setup.yaml).
+This template creates a role named `athenz.zms-service`
+
+
+### S3 bucket for ELB Access logs
+--
+Create S3 bucket needed to log ELB access logs with the following bucket policy
+
+```
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Sid": "",
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": "arn:aws:iam:::root"
+ },
+ "Action": "s3:PutObject",
+ "Resource": "arn:aws:s3:::/*/AWSLogs//*"
+ }
+ ]
+}
+```
+Refer [AWS ELB Documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-logging-bucket-permissions) for more details on bucket policy.
+
+### VPC Setup
+--
+Setup VPC using the cloudformation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/zms-setup/cloud-formation/athens-zms-aws-resource-setup.yaml) by giving the following mandatory parameters
+- `Route53HostedZoneName`
+- `Route53RecordName`
+- `S3AccessLogBucketName` (Created in the previous step)
+- `Environment`
+
+The other parameters are set by default. Change them as per your requirement
+
+*NOTE - Modifying the other defaults might require subsequent changes.*
+
+Following resources will be created after executing the template
+1. 2 availability zones
+1. Public & Private subnet for each availability zone
+1. 2 NAT gateways and elastic IPs
+1. NACL's for the subnets
+1. Internet gateways for all public subnets
+1. Route tables for all subnets
+1. Elastic load balancer
+1. Route 53 DNS entry
+1. ZMS Server and ELB security groups
+
+### RDS Setup
+--
+#### Create an Aurora MySQL cluster
+--
+Setup the cluster using cloudformation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/zms-setup/cloud-formation/athens-zms-aws-rds-setup.yaml) by giving the below mandatory parameters
+
+- `Route53HostedZoneName`
+- `Route53RecordName`
+- `DatabaseUsername`
+- `DatabasePassword`
+- `Environment`
+
+The other parameters are set by default. Change them as per your requirement
+
+#### Set up the schema
+--
+1. Create an instance in private subnet and login into it.
+After logging in, use the following commands to connect to the cluster
+ ```
+ mysql -h -P 3306 -u -p
+ ```
+1. Copy the [zms_server.sql](https://github.com/yahoo/athenz/blob/master/servers/zms/schema/zms_server.sql) file from the Athenz Git repository onto this host and create the database using the following command
+ ```
+ mysql -h -P 3306 -u -p < zms_server.sql
+ ```
+1. Create a user with full privileges on zms database created above. For eg. If your ZMS Server will be running on zms1.athenz.com and user to be created is `athenz-zms` having password `athenz-zms`
+ ```
+ CREATE USER 'athenz-zms'@'zms1.athenz.com' IDENTIFIED BY 'athenz-zms';
+ GRANT ALL PRIVILEGES ON zms_server TO 'athenz-zms'@'zms1.athenz.com';
+ FLUSH PRIVILEGES;
+ ```
+
+### Create S3 bucket to store zms data
+--------------------------------------
+
+Create S3 bucket for storing zms certificates & keys with appropriate policy as follows
+```
+{
+"Version": "2012-10-17",
+"Statement": [
+ {
+ "Sid": "",
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": "arn:aws:iam:::role/athenz.zms-service"
+ },
+ "Action": "s3:GetObject",
+ "Resource": "arn:aws:s3::: /*"
+ }
+ ]
+}
+```
+Also enable `Default Encryption` for your bucket.
+
+*NOTE - athenz.zms-service is the EC2 role created using IAM template above*
+
+#### Generate and upload service private key and id
+--
+Generate a unique private key that ZMS Server will use to sign any NTokens it issues
+```
+openssl genrsa -out service_private_key 2048
+openssl rsa -in service_private_key -pubout > zms_service_x509_key_public
+```
+Upload the service private key with name `service_private_key` onto the s3 bucket
+
+Upload the service private key id with name `service_private_key_id` onto the s3 bucket. This file just contains
+the id of private key. It is not mandatory as the id defaults to `0` if not specified
+
+#### Upload server X.509 cert and key
+--
+*NOTE - While it is still possible to generate and use a self-signed X509 certificate for ZMS Servers, it is recommended to
+purchase one for your production server from a well known certificate authority. Having such a certificate installed on your
+ZMS Servers will no longer require to distribute the server's CA certificate to other hosts (e.g. ZTS Servers, Hosts running ZPU).*
+- Follow the instructions provided by the Certificate Authority that you're going to purchase your certificate from, to generate your private key and Certificate Request (CSR).
+
+- If you are using self signed certs then run the following commands:
+ ```
+ openssl genrsa -des3 -out zms_ca_key 4096 (Create ZMS CA Key)
+ openssl req -x509 -new -nodes -key zms_ca_key -sha256 -days 1024 -out service_x509_ca_certs (Generate CA Cert)
+ openssl genrsa -out service_x509_key 2048 (Generate your private key)
+ openssl req -new -key service_x509_key -out service_x509_csr (Generate your CSR)
+ openssl x509 -req -in service_x509_csr -CA service_x509_ca_certs -CAkey zms_ca_key -CAcreateserial -out service_x509_cert -days 500 -sha256 (Generate your Certificate)
+ ```
+- Verify your certs
+ ```
+ openssl x509 -in service_x509_ca_certs -text -noout
+ openssl x509 -in service_x509_cert -text -noout
+ ```
+- Once you have received your X509 certificate and key,
+ - Upload the certificate to s3 bucket with name `service_x509_cert`
+ - Upload the private key with name `service_x509_key`
+ - Upload the Root CA cert with name `service_x509_ca_certs`
+
+#### Upload RDS CA Certs
+---
+
+RDS Certs are needed if you have set `athenz.zms.jdbc_use_ssl=` property in `zms.properties` to `true`. By default it is set to `false`
+
+- Upload the RDS CA Certs with key `service_rds_ca_certs`
+For details on AWS RDS Certs, Please refer [RDS CERTS AWS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html)
+
+#### Upload truststore password
+--
+- Upload password you want to use for truststore with name `service_x509_store_pwd`
+
+#### Upload ZMS DB User Password
+--
+- Create a file containing only the password for ZMS Database user(`athenz-zms`) created above during RDS schema setup
+- Upload the file to bucket with name `db_user_data`
+
+
+### Create S3 bucket for audit logs
+--
+Create another bucket for audit logs having the following bucket policy
+```
+{
+"Version": "2012-10-17",
+"Statement": [
+ {
+ "Sid": "",
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": [
+ "arn:aws:iam::488664618023:role/athenz.zms-service"
+ ]
+ },
+ "Action": [
+ "s3:AbortMultipartUpload",
+ "s3:GetBucketLocation",
+ "s3:GetObject",
+ "s3:ListBucket",
+ "s3:ListBucketMultipartUploads",
+ "s3:PutObject"
+ ],
+ "Resource": [
+ "arn:aws:s3:::",
+ "arn:aws:s3:::/*"
+ ]
+ }
+]
+}
+```
+### Edit Variables & Properties
+--
+#### Edit aws_init.sh
+--
+Update the bucket names, domain admin and RDS Endpoint in `athenz/aws-setup/zms-setup/build/bin/aws_init.sh` by editing the below lines
+```
+export ZMS_DATA_BUCKET_NAME=""
+export ZMS_AUDIT_LOG_BUCKET_NAME=""
+export DOMAIN_ADMINS=""
+export RDS_MASTER=""
+```
+When running the server very first time, ZMS Server automatically creates the required domains and sets the running user as the system administrator.
+The system administrators are the only ones authorized to create top level domains in Athenz.
+Before running the server very first time, you can configure the set of system administrators who are authorized to create top level
+domains in Athenz. Set DOMAIN_ADMIN to unix user id that you want to add as Athenz system administrator.
+The password for this user is uploaded to ZMS Data S3 Bucket created above with name `admin_pass`
+
+- Create a file containing password for ZMS Domain Admin
+- Upload the file to bucket with name `admin_pass`
+
+The other variables are for trust store & key store setup. We recommend to use the defaults but if you change then update the corresponding values in `athenz.properties` file discussed later.
+
+#### Edit the zms.properties file
+--
+The following properties need to be edited in `zms.properties` file located at `athenz/aws-setup/zms-setup/build/conf/zms.properties`
+
+##### Database Access
+--
+Modify the following settings if RDS username & RDS password filename (stored on S3) are different from defaults suggested above.
+```
+athenz.zms.object_store_factory_class=com.yahoo.athenz.zms.store.impl.JDBCObjectStoreFactory
+athenz.zms.jdbc_user=athenz-zms
+athenz.zms.jdbc_password=db_user_data
+```
+##### User Authentication
+--
+For a user to authenticate himself/herself in ZMS, the server must have the appropriate authentication authority implementation configured. By default, ZMS enables the following two authorities:
+- Unix User Authority - using pam login profile to authenticate users
+- Principal Authority - validating Principal Tokens that are issued when users authenticate using their unix login password.
+- This is set using the following properties
+ `athenz.zms.authority_classes=com.yahoo.athenz.auth.impl.PrincipalAuthority,com.yahoo.athenz.auth.impl.UserAuthority`
+
+The server also provides other authorities - e.g. Kerberos, TLS Certificate that are not enabled by default.
+
+To add your own authentication authority modify the
+`athenz.zms.authority_classes=com.yahoo.athenz.auth.impl.PrincipalAuthority,com.yahoo.athenz.auth.impl.UserAuthority`
+line in `zms.properties` file and include comma separated list of authority implementation classes to support.
+
+##### Domain Admins
+--
+Modify the below setting and set it to unix user you passed as domain admin in `aws_init_file` in above steps.
+
+`athenz.zms.domain_admin=user.zms-admin`
+
+#### Edit the athenz.properties file
+--
+The following properties need to be edited in `athenz.properties` file located at `athenz/aws-setup/zms-setup/build/conf/athenz.properties`
+
+
+##### Truststore and Keystore Settings
+--
+- If you modified the truststore and keystore paths and password in the `aws_init.sh` file then change the below settings in `athenz.properties` file accordingly
+ - `athenz.ssl_key_store=/opt/zms/conf/zms_keystore.pkcs12` `//path to the keystore file that contains the server's certificate`
+ - `athenz.ssl_key_store_type=PKCS12` `//specifies the type for the keystore specified in the`
+ - `athenz.ssl_key_store_password=service_x509_store_pwd` `//S3 bucket key name for Password for the keystore specified in the athenz.ssl_key_store property`
+ - `athenz.ssl_trust_store=/opt/zms/conf/zms_truststore.jks` `//path to the trust store file that contains CA certificates trusted by this Jetty instance`
+ - `athenz.ssl_trust_store_type=JKS` `//specifies the type for the truststore specified`
+ - `athenz.ssl_trust_store_password=service_x509_store_pwd` `//password for the truststore`
+
+### Packer
+--
+#### Packer VPC Setup
+
+Setup packer vpc by using the cloudformation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/cloud-formation/packer_vpc.yaml)
+and update `packer.json` file accordingly.
+```
+{
+ "subnet_id":"",
+ "vpc_id": "",
+ "aws_region": "",
+ "aws_ami_name": "zms-aws-cd-image",
+ "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
+ "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}",
+ "aws_session_token": "{{env `AWS_SESSION_TOKEN`}}",
+ "ssh_keypair_name":"",
+ "ssh_private_key_file":"",
+ "source_ami": "ami-02c71d7a"
+}
+```
+
+#### Build ZMS image
+--
+Build the image with packer using the following command
+
+```
+cd /aws-setup/zms-setup
+packer build packer/aws/packer.json
+```
+
+### Deploy ZMS
+--
+Run cloud formation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/zms-setup/cloud-formation/athenz-zms-aws-instance-deployment.yaml) to bring up the zms-instances in 2 availability zones.
+- The imageID parameter should be set to the image created in previous step.
+
+The ZMS Server is now up and running.
+
diff --git a/docs/aws_zts_setup.md b/docs/aws_zts_setup.md
new file mode 100644
index 00000000000..399d1fdb99d
--- /dev/null
+++ b/docs/aws_zts_setup.md
@@ -0,0 +1,350 @@
+# Setup ZTS on AWS
+-------------------
+- [AWS Resource Setup](###-aws-resource-setup)
+ - [IAM role setup](####-iam-role-setup)
+ - [VPC setup](####-vpc-setup)
+ - [RDS Setup](####-rds-setup)
+ - [Create Aurora Mysql cluster](#####-create-an-aurora-mysql-cluster)
+ - [Schema setup](#####-set-up-the-schema)
+ - [S3 bucket for zts data](####-create-s3-bucket-to-store-zts-data)
+ - [Generate and upload service private key and Id](#####-generate-and-upload-service-private-key-and-id)
+ - [Upload server X.509 cert and key](#####-upload-server-x.509-cert-and-key)
+ - [Upload RDS CA Certs](#####-upload-rds-ca-certs)
+ - [Upload truststore password](#####-upload-truststore-password)
+ - [Upload ZTS DB User Password](#####-upload-zts-db-user-password)
+ - [Upload ZMS CA Certs](#####-upload-zms-ca-certs)
+ - [Upload ZTS and ZMS Public keys](#####-upload-zts-and-zms-public-keys)
+ - [Upload Self Cert Signer Key](#####-upload-self-cert-signer-key)
+ - [Update the policy for S3 bucket for Audit logs](####-create-s3-bucket-for-audit-logs)
+ - [Update ZMS DATA BUCKET](####-update-zms-data-bucket)
+ - [Register ZTS Service](####-register-zts-service)
+ - [Edit Variables & Properties](####-edit-variables-&-properties)
+ - [aws_init.sh](#####-edit-aws_init.sh)
+ - [Edit the properties file](#####-edit-the-properties-file)
+ - [Database Access](######-database-access)
+ - [Athenz CA X.509 Certificate Issuing](######-athenz-car-x.509-certificate-issuing)
+ - [Truststore and Keystore Settings](######-truststore-and-keystore-settings)
+ - [Packer](####-packer)
+ - [Packer VPC setup](#####-packer-vpc-setup)
+ - [Build ZTS Image](#####-build-zts-image)
+ - [Deploy ZTS](####deploy-zts)
+
+## AWS Resource Setup
+-------------
+
+### IAM role setup
+--
+Create EC2 profile role for zts using cloudformation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/zts-setup/cloud-formation/athens-zts-aws-roles-setup.yaml).
+This template creates a role named `athenz.zts-service`
+
+### VPC Setup
+--
+Setup VPC using the cloudformation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/zts-setup/cloud-formation/athens-zts-aws-resource-setup.yaml) and giving the following mandatory parameters
+- `Route53HostedZoneName`
+- `Route53RecordName`
+- `S3AccessLogBucketName`(Created during Zms Setup)
+- `Environment`
+
+The other parameters are set by default. Change them as per your requirement
+
+*NOTE - Modifying the other defaults might require subsequent changes.*
+
+Following resources will be created after executing the template
+1. 2 availability zones
+1. Public & Private subnets for zts in each availability zone
+1. Public & Private subnets for cert signer in each availability zone
+1. 4 NAT gateways and elastic IPs
+1. NACL's for the subnets
+1. Internet gateways for all public subnets
+1. Route tables for all subnets
+1. Elastic load balancer
+1. Route 53 DNS entry
+1. ZTS Server & ELB security groups
+
+### RDS Setup
+--
+#### Create an Aurora MySQL cluster
+--
+Setup the cluster using cloudformation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/zts-setup/cloud-formation/athens-zts-aws-rds-setup.yaml) by giving the below mandatory parameters
+
+- `Route53HostedZoneName`
+- `Route53RecordName`
+- `DatabaseUsername`
+- `DatabasePassword`
+- `Environment`
+
+The other parameters are set by default. Change them as per your requirement
+
+#### Set up the schema
+--
+1. Create an instance in private subnet and login into it.
+After logging in, use the following commands to connect to the cluster using Database Root Credentials
+ ```
+ mysql -h -P 3306 -u -p
+ ```
+1. Copy the [zts_server.sql](https://github.com/yahoo/athenz/blob/master/servers/zts/schema/zts_server.sql) file from the Athenz Git repository onto this host and create the database using the following command
+ ```
+ mysql -h -P 3306 -u -p < zts_server.sql
+ ```
+1. Create a user with full privileges on zts database created above. Foe eg. If your ZTS Server will be running on zts1.athenz.com and user to be created is `athenz-zts` having password `athenz-zts`
+ ```
+ CREATE USER 'athenz-zts'@'zts1.athenz.com' IDENTIFIED BY 'athenz-zts';
+ GRANT ALL PRIVILEGES ON zts_store TO 'athenz-zts'@'zts1.athenz.com';
+ FLUSh PRIVILEGES;
+ ```
+
+### Create S3 bucket to store zts data
+--------------------------------------
+
+Create S3 bucket for storing zts certificates & keys with appropriate policy as follows
+```
+{
+"Version": "2012-10-17",
+"Statement": [
+ {
+ "Sid": "",
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": "arn:aws:iam:::role/athenz.zts-service"
+ },
+ "Action": "s3:GetObject",
+ "Resource": "arn:aws:s3::: /*"
+ }
+ ]
+}
+```
+Also enable Default Encryption for your bucket.
+
+*NOTE - athenz.zts-service is the EC2 role created using IAM template above*
+
+#### Generate and upload service private key and id
+--
+Generate a unique private key that ZTS Server will use to sign any NTokens it issues
+```
+openssl genrsa -out service_private_key 2048
+openssl rsa -in service_private_key -pubout > zts_service_x509_key_public
+```
+Upload the service private key with name `service_private_key` onto the s3 bucket
+
+Upload the service private key id with name `service_private_key_id` onto the s3 bucket. This file just contains
+the id of private key. It is not mandatory as the id defaults to `0` if not specified
+
+#### Upload server X.509 cert and key
+--
+*NOTE - While it is still possible to generate and use a self-signed X509 certificate for ZTS Servers,
+it is recommended to purchase one for your production server from a well known certificate authority.
+Having such a certificate installed on your ZTS Servers will no longer require to distribute the
+server's public certificate to other hosts (e.g. Hosts running ZPU).*
+
+- Follow the instructions provided by the Certificate Authority that you're going to purchase your certificate from, to generate your private key and Certificate Request (CSR).
+- If you are using self signed certs then run the following commands:
+ ```
+ openssl genrsa -des3 -out zts_ca_key 4096 (Create ZTS CA Key)
+ openssl req -x509 -new -nodes -key zts_ca_key -sha256 -days 1024 -out service_x509_ca_certs (Generate CA Cert)
+ openssl genrsa -out service_x509_key 2048 (Generate your private key)
+ openssl req -new -key service_x509_key -out service_x509_csr (Generate your CSR)
+ openssl x509 -req -in service_x509_csr -CA service_x509_ca_certs -CAkey zts_ca_key -CAcreateserial -out service_x509_cert -days 500 -sha256 (Generate your Certificate)
+ ```
+- Verify your certs
+ ```
+ openssl x509 -in service_x509_ca_certs -text -noout
+ openssl x509 -in service_x509_cert -text -noout
+ ```
+- Once you have received your X509 certificate and key,
+ - Upload the certificate with on s3 bucket with name `service_x509_cert`
+ - Upload the private key with name `service_x509_key`
+ - Upload the Root CA cert with name `service_x509_ca_certs`
+
+#### Upload RDS CA Certs
+---
+- Upload the RDS CA Certs with key `service_rds_ca_certs`
+
+For details on AWS RDS Certs, Please refer [RDS CERTS AWS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html)
+
+#### Upload truststore password
+--
+- Upload password you want to use for truststore with name `service_x509_store_pwd`
+
+#### Upload ZTS DB User Password
+--
+- Create a file containing only the password for ZTS Database user(`athenz-zts`) created above during RDS schema setup
+- Upload the file to bucket with name `db_user_data`
+
+#### Upload ZMS CA Certs
+
+- Upload ZMS CA Cert with key `zms_service_x509_ca_certs`. They will be added to ZTS truststore so that ZTS can communicate securely with ZMS
+
+#### Upload ZTS and ZMS Public keys
+
+- Upload ZTS public key with name `zts_service_x509_key_public.pem `
+- Upload ZMS public key with name `zms_service_x509_key_public.pem `
+
+They are required to generate athenz.conf file at `/opt/zts/conf` to include the ZTS and ZMSServer URL
+and the registered public keys that the athenz client libraries and utilities will
+use to establish connection and validate any data signed by the ZTS and ZMS Server:
+
+#### Upload Self Cert Signer Key
+
+You can use SelfCertSigner or have your implementation of Cert Signer.
+
+Refer [Certificate Signer](cert_signer.md) for full details how to implement your cert signer.
+
+If you are using self cert signer then
+
+- Generate a private key and upload it to s3 bucket with name `self_cert_signer_key`
+
+### Update the policy for S3 bucket for Audit logs
+
+Update the bucket policy for S3 bucket created for audit logs during zms setup to allow `athenz.zts-service`
+role to read and write to it.
+
+```
+{
+"Version": "2012-10-17",
+"Statement": [
+ {
+ "Sid": "",
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": [
+ "arn:aws:iam:::role/athenz.zms-service"
+ "arn:aws:iam:::role/athenz.zts-service"
+ ]
+ },
+ ...
+]
+}
+```
+### Update ZMS DATA BUCKET
+
+- Upload zts service public key to ZMS Data Bucket with key `zts_service_x509_key_public.pem`
+
+### Register ZTS Service
+In order for ZTS to access ZMS domain data, it must identify itself
+as a registered service in ZMS. Use `zms-cli` utility to
+register a new service in `sys.auth` domain. If ZMS Servers are
+running with a X509 certificate from a well know certificate
+authority (not a self-signed one) we don't need to reference the CA
+cert like we are doing below for self signed certs.
+
+Login into your zms-server instance as domain admin you created during zms setup and run the below commands:
+
+```
+- Download ZMS CA Certs(If using self signed certs)
+ aws s3 cp s3:///zms_service_x509_ca_certs /tmp/zms_service_x509_ca_certs
+- Download ZTS public key
+ aws s3 cp s3:// /zts_service_x509_key_public.pem /tmp/zts_service_x509_key_public.pem
+- Register Service using zms-cli
+ /opt/zts/bin/zms-cli -c /tmp/service_x509_ca_certs -z -d sys.auth add-service zts 0 /tmp/zts_service_x509_key_public.pem
+```
+*NOTE - Append /zms/v1 to your url in the command above*
+
+For e.g. If your zms server is running at https://athenz.zms.com:4443 then pass `https://athenz.zms.com:4443/zms/v1`.
+
+### Edit Variables & Properties
+--
+#### Edit aws_init.sh
+--
+Update the bucket names in `athenz/aws-setup/zts-setup/build/bin/aws_init.sh` by editing the below lines
+```
+export ZTS_DATA_BUCKET_NAME=""
+export ZTS_AUDIT_LOG_BUCKET_NAME=""
+export ZTS_URL=""
+export ZMS_URL="""
+export RDS_MASTER=""
+```
+The other variables are for trust store & key store setup. We recommend to use the defaults but if you change then update the corresponding values in `athenz.properties` file discussed later.
+
+#### Edit the properties file
+--
+
+##### Database Access
+--
+Modify the following settings in `zts.properties` file located at `athenz/aws-setup/zts-setup/build/conf/zts.properties` if RDS username & RDS password filename (stored on S3) are different from defaults suggested above.
+```
+athenz.zts.cert_record_store_factory_class=com.yahoo.athenz.zts.cert.impl.JDBCCertRecordStoreFactory
+athenz.zts.cert_jdbc_user=athenz-zts
+athenz.zts.cert_jdbc_password=db_user_data
+```
+
+##### Athenz CA X.509 Certificate Issuing
+--
+
+For authenticating services using X509 certificates, ZTS Servers expect the configured cert signer factory class names in its athenz.zts.cert_signer_factory_class system property.
+Self Cert Signer `com.yahoo.athenz.zts.cert.impl.SelfCertSignerFactory` is a sample implementation of cert Signer we have for development environment.
+You can use SelfCertSigner or have your implementation of Cert Signer.
+
+If you are using self cert signer make the below changes
+
+The self cert signer key you uploaded in above steps has to be downloaded on the box. The default is to download
+it to `/opt/zts/conf/self_cert_signer_key`. If you using the defaults, uncomment the below lines in `initialize_zts.sh`
+
+```
+# echo "Downloading self cert signer key"
+# aws s3 cp s3://$bucket_name/self_cert_signer_key /opt/zts/conf/self_cert_signer_key
+```
+
+Edit the below properties in `zts.properties` file accordingly:
+
+```
+# athenz.zts.self_signer_private_key_fname=/opt/zts/conf/self_cert_signer_key
+
+#athenz.zts.self_signer_private_key_password=
+
+# athenz.zts.self_signer_cert_dn=C=US,ST=CA,L=Sunnyvale,O=Oath,OU=Athenz,CN=zts.aws.oath.cloud.
+```
+
+#### Truststore & Keystore Settings
+--
+- If you modified the truststore and keystore paths and password in the `aws_init.sh` file then change the below settings in `athenz.properties` file located at `athenz/aws-setup/zts-setup/build/conf/athenz.properties`
+ - `athenz.ssl_key_store=/opt/zts/conf/zts_keystore.pkcs12` `//path to the keystore file that contains the server's certificate`
+ - `athenz.ssl_key_store_type=PKCS12` `//specifies the type for the keystore specified in the`
+ - `athenz.ssl_key_store_password=service_x509_store_pwd` `//S3 bucket key name for Password for the keystore specified in the athenz.ssl_key_store property`
+ - `athenz.ssl_trust_store=/opt/zts/conf/zts_truststore.jks` `//path to the trust store file that contains CA certificates trusted by this Jetty instance`
+ - `athenz.ssl_trust_store_type=JKS` `//specifies the type for the truststore specified`
+ - `athenz.ssl_trust_store_password=service_x509_store_pwd` `//password for the truststore`
+
+- Update the following in zts.properties file
+ - `athenz.zts.ssl_key_store=/opt/zts/conf/zts_keystore.pkcs12` `//path to the keystore file that contains the server's certificate`
+ - `athenz.zts.ssl_key_store_type=PKCS12` `//specifies the type for the keystore specified in the`
+ - `athenz.zts.ssl_key_store_password=service_x509_store_pwd` `//S3 bucket key name for Password for the keystore specified in the athenz.ssl_key_store property`
+ - `athenz.zts.ssl_trust_store=/opt/zts/conf/zts_truststore.jks` `//path to the trust store file that contains CA certificates trusted by this Jetty instance`
+ - `athenz.zts.ssl_trust_store_type=JKS` `//specifies the type for the truststore specified`
+ - `athenz.zts.ssl_trust_store_password=service_x509_store_pwd` `//password for the truststore`
+
+### Packer
+--
+#### Packer VPC Setup
+
+Packer VPC was set during zms setup, update `packer.json` accordingly.
+```
+{
+ "subnet_id":"",
+ "vpc_id": "",
+ "aws_region": "",
+ "aws_ami_name": "zts-aws-cd-image",
+ "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
+ "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}",
+ "aws_session_token": "{{env `AWS_SESSION_TOKEN`}}",
+ "ssh_keypair_name":"",
+ "ssh_private_key_file":"",
+ "source_ami": "ami-02c71d7a"
+}
+```
+
+#### Build ZTS image
+--
+Build the image with packer using the following command
+
+```
+cd /aws-setup/zts-setup
+packer build packer/aws/packer.json
+```
+
+### Deploy ZTS
+--
+Run cloud formation [template](https://github.com/yahoo/athenz/blob/master/aws-setup/zts-setup/cloud-formation/athenz-zts-aws-instance-deployment.yaml) to bring up the zts-instances in 2 availability zones.
+- The imageID parameter should be set to the image created in above step.
+
+The ZTS Server is now up and running.
+
diff --git a/docs/setup_zts.md b/docs/setup_zts.md
index 2f1f4a0d5ce..fbe6157eca1 100644
--- a/docs/setup_zts.md
+++ b/docs/setup_zts.md
@@ -75,7 +75,7 @@ is a sample implementation of cert Signer we have for development environment.
You can use SelfCertSigner or have your implementation of Cert Signer.
-Refer [cert signer](cert_signer_store.md) for full details how to implement your cert signer.
+Refer [Certificate Signer](cert_signer.md) for full details how to implement your cert signer.
## Start/Stop ZTS Server
------------------------
diff --git a/ui/config/default-config.js b/ui/config/default-config.js
index 6e5fd6ee8ae..f0f94373363 100644
--- a/ui/config/default-config.js
+++ b/ui/config/default-config.js
@@ -30,7 +30,7 @@ const config = {
},
userLink: function (user) {
const domain = process.env.UI_SERVER || 'localhost';
- return 'https://' + domain + ':9443/athenz/domain/create/userdomain';
+ return 'https://' + domain + ':443/athenz/domain/create/userdomain';
},
headerLinks: [
{title: 'Website', url: 'http://www.athenz.io', target: '_blank'},
@@ -65,7 +65,7 @@ const config = {
},
userLink: function (user) {
const domain = process.env.UI_SERVER || 'localhost';
- return 'https://' + domain + ':9443/athenz/domain/create/userdomain';
+ return 'https://' + domain + ':443/athenz/domain/create/userdomain';
},
headerLinks: [
{title: 'Website', url: 'http://www.athenz.io', target: '_blank'},
diff --git a/ui/server.js b/ui/server.js
index b8c5b40bcb1..950cd4b3033 100644
--- a/ui/server.js
+++ b/ui/server.js
@@ -25,4 +25,4 @@ var options = {
passphrase: 'athenz'
};
-https.createServer(options, app).listen(9443);
+https.createServer(options, app).listen(443);
diff --git a/ui/test/unit/utils/view.js b/ui/test/unit/utils/view.js
index 2d3a32e996c..d8cd6a03fce 100644
--- a/ui/test/unit/utils/view.js
+++ b/ui/test/unit/utils/view.js
@@ -85,12 +85,12 @@ describe('view utils', function() {
'fullName': 'role',
'name': 'role',
'type': 'Regular',
- 'members': [{'name': 'a'}, {'name': config.userDomain + '.b', 'userlink': 'https://localhost:9443/athenz/domain/create/userdomain'}],
+ 'members': [{'name': 'a'}, {'name': config.userDomain + '.b', 'userlink': 'https://localhost:443/athenz/domain/create/userdomain'}],
'auditLog': [{
'action': 'ADD',
- 'admin': {'name': config.userDomain + '.a', 'userlink': 'https://localhost:9443/athenz/domain/create/userdomain'},
+ 'admin': {'name': config.userDomain + '.a', 'userlink': 'https://localhost:443/athenz/domain/create/userdomain'},
'created': '2016-06-28T23:28:29.000Z',
- 'member': {'name': config.userDomain + '.b', 'userlink': 'https://localhost:9443/athenz/domain/create/userdomain'}
+ 'member': {'name': config.userDomain + '.b', 'userlink': 'https://localhost:443/athenz/domain/create/userdomain'}
}]
}
);