- Set the default region for Terraform in
infra/variables.tf
. - Within the
routing config
file andAPI routing config
file there will be a field namedhosted_zones
. Add your organization's domain(s) as the key and the Route53 Hosted Zone ID as the value. - In the
handler config
add the Slack Channel and Redirect Link:channel
: Slack channel used to send error messages.redirect
: Redirect link to your team's on-call channel.- To get the redirect link login to app.slack.com on the web and open the channel you want to redirect messages to.
- The URL for that page should be in the format:
app.slack.com/client/{VALUE_1}/{VALUE_2}
VALUE_1
is used for theteam
field andVALUE_2
is used for theid
field.
infra/otter.tf
: Terraform Module for Ottr Core Platform
Variable | Optional | Type | Description | Default | Example |
---|---|---|---|---|---|
acme_subdelegate_zone | False | string | Route53 Zone to be Created for DNS Subdelegation | "company-acme.com" | |
hosted_zone_ids | False | List[string] | Route53 Hosted Zone IDs within Organization | ["arn:aws:route53:::hostedzone/XXXXXXXXXXXXXX"] | |
subnet_cidr_block | False | List[string] | IP CIDR Blocks for Subnets AZ1 and AZ2 | ["10.0.1.0/24", "10.0.2.0/24"] | |
subnet_az1 | False | string | Subnet ID for Primary Availability Zone | "subnet-0123456a" | |
subnet_az2 | False | string | Subnet ID for Secondary Availability Zone | "subnet-0123456b" | |
private_subnet | False | bool | subnet_az1/az2 Runs in Private Subnet | true | |
vpc_id | False | string | VPC ID | "vpc-12345678" | |
country | False | string | Certificate Signing Request: Country (C) | "US" | |
state | False | string | Certificate Signing Request: State (ST) | "CA" | |
locality | False | string | Certificate Signing Request: Locality (L) | "San Francisco" | |
False | string | Certificate Signing Request: Email (EMAIL) | "[email protected]" | ||
organization | False | string | Certificate Signing Request: Organization Name (O) | "Company, Inc." | |
organization_unit | False | string | Certificate Signing Request: Organization Unit (OU) | "Security" | |
prefix | True | string | Secrets Manager Prefix Path | prod | development |
region | True | string | AWS Region | "us-east-1" | "us-west-1" |
cloudwatch_schedule | True | string | CloudWatch Event Frequency to Execute Ottr | "rate(1 day)" | "rate(12 hours)" |
database | True | string | RDS Database Name | "otter" | "otter-db" |
infra/api.tf
: Terraform Module for Ottr API (API Module)
Variable | Optional | Type | Description | Default | Example |
---|---|---|---|---|---|
ingress_ip_ranges | False | List[string] | IP CIDR Blocks for Ingress Traffic on API | ["172.16.0.0/24", 172.16.1.0/24] | |
subnet_cidr_block | False | List[string] | IP CIDR Blocks for Subnets AZ1 and AZ2 | ["10.0.1.0/24", "10.0.2.0/24"] | |
subnet_az1 | False | string | Subnet ID for Primary Availability Zone | "subnet-0123456a" | |
subnet_az2 | False | string | Subnet ID for Secondary Availability Zone | "subnet-0123456b" | |
vpc_id | False | string | VPC ID | "vpc-12345678" | |
hosted_zone_ids | False | List[string] | Route53 Hosted Zone ID ARNs within Organization | ["arn:aws:route53:::hostedzone/XXXXXXXXXXXXXX"] | |
api_zone_id | False | string | Route53 Hosted Zone ID API will Reside | "XXXXXXXXXXXXXX" | |
api_domain_name | False | string | FQDN of API (Domain Must Match api_zone_id Domain) | "ottr.example.com" | |
internal_alb | True | boolean | Internal Load Balancer in Private Subnets | true | true |
region | True | string | AWS Region | "us-east-1" | "us-west-1" |
instance_type | True | string | EC2 Instance Type for ECS Cluster | "t2.small" | "t2.medium" |
ec2_minimum_capacity | True | string | Minimum Number of Instances in ECS Cluster | 1 | 2 |
ec2_maximum_capacity | True | string | Maximum Number of Instances in ECS Cluster | 2 | 3 |
ec2_desired_capacity | True | string | Desired Number of Instances in ECS Cluster | 2 | 2 |
Note: If internal_alb
is set to true you will need to create an DNS CNAME Record
for your internal DNS servers to point api_domain_name
to the Application Load
Balancer DNS record. If internal_alb is set to false this is handled
automatically for you in Route53 since the API will be externally facing.
infra/api.tf
: Terraform Module for Ottr API (ACM Module)
Variable | Optional | Type | Description | Default | Example |
---|---|---|---|---|---|
domain_name | False | string | Address for Ottr API (Must Own Route53 Domain) | "ottr.example.com " |
|
zone_id | False | string | Route53 Hosted Zone ID for domain_name Variable |
"Z2ZBSSGGIDRSTL" [Hosted Zone ID for example.com ] |
|
subject_alternative_names | True | List[string] | Subject Alternative Names for Certificate | ["sub.example.com ", "test.example.com "] |
# Download Terraform
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
# Activate Virtual Environment
source ottr-venv/bin/activate
cd $HOME/Desktop/ottr-venv/ottr/infra
# Build Ottr and Ottr API Infrastructure
terraform init
terraform apply
After the infrastructure is built, the value set in acme_subdelegate_zone
will
create a Route53 Hosted Zone which will be used for DNS Subdelegation. You will
need to either own or purcahse that domain and use Route53 as the DNS service
for the domain in use: Configuring Route53 as a DNS Service
When Ottr executes an ECS task, that in turn starts up a container that has the logic required to perform an end-to-end certificate rotation process. The container that is launched depends on Platform, OS Version, Device Model, and Certificate Authority. Once that container runs, it will first need to establish a connection to the device since requests are made either through HTTP Requests or an SSL Client.
infra/secrets.tf
references the Terraform module that creates secrets within AWS Secrets Manager for each platform.- Once the secrets are created, within AWS Secrets Manager search
[PREFIX]/otter/[PLATFORM_NAME]
and update the secrets value with ausername
andpassword
field underSecret key/value
. These credentials are used to authenticate against a specified platform (i.e. PanOS) during container runtime.
For error handling Ottr uses Slack as a notification mechanism for any certificate
rotation failures. You can modify this for your organization's use case within
the handler
function but if you prefer to use Slack you will need to create a
Slack App.
- Create Slack App:
https://api.slack.com/apps
- Define OAuth & Permissions:
chat:write
incoming-webhook
- Generate OAuth Token and to Copy into AWS Secrets Manager Under
Plaintext
:xoxb-xxx
(Bot User OAuth Token) →[PREFIX]/otter/slack
After the infrastructure is built the API will be reachable from the DNS Name from the Application Load Balancer. Since we have already created a certificate using Certificate Manager we will need to point a DNS CNAME Record from the Certificate Manager certificate Domain Name to the ALB DNS Name. Depending on how your infrastructure is built this will be done either through Route53 or your organization's internal DNS.
Now we move onto the configuring authentication for the API which RS256 to sign the JSON Web Token:
-
Create Public/Private Key Pair and Upload Private Key to AWS Secrets Manager under
[PREFIX]/otter/private_key
.openssl genrsa -out ottr.pem 4096 openssl rsa -in ottr.pem -pubout -out ottr_pub.pem
-
Copy the Public Key from
ottr_pub.pem
and write value in Secrets Manager at [PREFIX]/otter/public_key under the Plaintext type. -
Copy the Private Key from
ottr.pem
and write value in Secrets Manager at [PREFIX]/otter/private_key under the Plaintext type. -
Build the API container, push image to ECR, and restart the ECS Service for Ottr API.
cd $HOME/Desktop/ottr-venv/ottr make build-api AWS_REGION=xxx AWS_ACCOUNT_ID=xxx TABLE=xxx PREFIX=xxx
Environmental variables are referenced in
otter.tf
.AWS_REGION
→region
field inotter.tf
(Default:us-east-1
)TABLE
→database
field inotter.tf
(Default:otter
)PREFIX
→prefix
field inotter.tf
(Default:prod
)AWS_ACCOUNT_ID
→ AWS Account ID
-
Install Packages to Virtual Environment
cd $HOME/Desktop/ottr-venv/ottr/api/setup pip3 install -r requirements.txt
-
Take the Private Key
ottr.pub
and add it to the PRIVATE_KEY variables in thesetup
file.cd $HOME/Desktop/ottr-venv/ottr/api/setup python3 credentials.py
-
Copy
Bearer XYZ
Output and Cerate User in API Using thePOST /admin/v1/users
Endpoint by Using Bearer Token in Authorization Header-
This will be an administrative user that will have the capability of generating other users within your organization. You can authenticate against the
POST /user/v1/authenticate
Endpoint.# /admin/v1/users Authorization Header Bearer XYZ # /admin/v1/users Endpoint Payload { "username": "string", "password": "string", "role": "ADMIN" }
-
-
Delete
PRIVATE_KEY
fromsetup
file.
Continue at SETUP.md
to complete the remainder of setup.
Built runtime containers and push to ECR registry.
cd $HOME/Desktop/ottr-venv/ottr/
make build-containers-release AWS_REGION=[VALUE] AWS_ACCOUNT_ID=[VALUE]