Deploy using Installer to AWS EKS
Paramify can be deployed using the Paramify Platform Installer into an existing Kubernetes cluster, such as AWS EKS, Azure AKS, or self-managed.
The following instructions are an example of how to deploy the infrastructure and application into AWS EKS.
Prerequisites
- AWS CLI and SSO login with sufficient permissions to create resources
- Terraform CLI installed
- kubectl CLI installed
- An available subdomain planned to access the application (e.g., paramify.mycompany.com)
- A Paramify license file
- (Recommended) Credentials for an SMTP server to send email
- (Recommended) Access to configure Google Cloud Console, Microsoft Account Login, or Okta for SSO
NOTE
You'll need to configure at least one authentication method (e.g., SMTP, Google, MS, Okta) to be able to login to Paramify.
1. Create Infrastructure
Paramify will use the following infrastructure in AWS:
- EKS cluster in a new VPC
- RDS PostgreSQL database
- S3 bucket for generated documentation
To simplify creation of the infrastructure you can use the example Terraform file aws-paramify-eks-infra.tf to create everything in an isolated VPC. Be sure to update the variables at the top of the file according to your environment.
Follow these steps to create the infrastructure:
- Create an AWS SSL certificate for the desired subdomain (e.g., paramify.mycompany.com) in ACM
- Update and apply the terraform example (or similar):
- In an empty directory, save and edit the example
aws-paramify-eks-infra.tffile to set the variables for your environment - Init and check the configuration:
bashterraform init terraform planterraform init terraform plan- Apply the configuration to create AWS resources:
bashterraform applyterraform applyINFO
This will usually take a few minutes.
- Copy the convenience output values (or run
terraform output) that look something like:
cluster_name = "paramify-mycompany-eks" db_dns = "paramify-mycompany-db.abcdef123456.us-west-2.rds.amazonaws.com" region = "us-west-2" s3_bucket = "paramify-mycompany-s3" s3_role = "arn:aws:iam::012345678901:role/paramify-mycompany-eks-sa-role"cluster_name = "paramify-mycompany-eks" db_dns = "paramify-mycompany-db.abcdef123456.us-west-2.rds.amazonaws.com" region = "us-west-2" s3_bucket = "paramify-mycompany-s3" s3_role = "arn:aws:iam::012345678901:role/paramify-mycompany-eks-sa-role" - In an empty directory, save and edit the example
2. Prepare Installer
Follow these steps to prepare the Admin Console installer:
Connect
kubectlto your new EKS cluster, replacing your values similar to the following:bashaws eks update-kubeconfig --region us-west-2 --name paramify-mycompany-eks --profile=admin kubectl get nsaws eks update-kubeconfig --region us-west-2 --name paramify-mycompany-eks --profile=admin kubectl get nsThe second command should confirm ability to communicate with your cluster if it returns entries like
default,kube-system, etc.TIP
The parameter
--profile=adminrefers to your desired AWS SSO profile. If your default profile has sufficient permissions this may be optional.Add the KOTS plugin to kubectl:
bashcurl https://kots.io/install | sudo bashcurl https://kots.io/install | sudo bashStartup the installer in the EKS cluster:
bashkubectl kots install paramifykubectl kots install paramifyAfter choosing your desired namespace (i.e., paramify) it should prompt for a password to set on the installer. The Admin Console will then be installed and pause with the following message:
• Press Ctrl+C to exit • Go to http://localhost:8800 to access the Admin Console• Press Ctrl+C to exit • Go to http://localhost:8800 to access the Admin Console
3. Deploy Paramify
At this point the configuration and deployment will be similar to other Paramify deployment methods.
Open the installer URL at the local URL (e.g., http://localhost:8800)
Login using the admin password previously set while preparing the installer
Upload your Paramify License file
Enter your Paramify configuration information then continue
- The "Application Base URL" should match the DNS subdomain you chose (e.g., https://paramify.company.com)
- For "Ingress Setting" choose "Load Balancer" and enter the following:
- Under "Load Balancer Annotations" enter:
yamlservice.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-west-2:<account_id>:certificate/<cert_id> # replace with your SSL cert service.beta.kubernetes.io/aws-load-balancer-ssl-ports: http service.beta.kubernetes.io/aws-load-balancer-backend-protocol: https service.beta.kubernetes.io/load-balancer-source-ranges: "1.2.3.4/32,0.0.0.0/0" # replace with your IP addresses, or remove for public accessservice.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-west-2:<account_id>:certificate/<cert_id> # replace with your SSL cert service.beta.kubernetes.io/aws-load-balancer-ssl-ports: http service.beta.kubernetes.io/aws-load-balancer-backend-protocol: https service.beta.kubernetes.io/load-balancer-source-ranges: "1.2.3.4/32,0.0.0.0/0" # replace with your IP addresses, or remove for public access - For "Database" select "External Postgres"
- As "Database Host" enter the
db_dnsfrom terraform output of the created RDS database. - Set "User" to "postgres" and "Password" to the DB password you set in the
.tffile variable. - The other settings can be left at default (e.g., port is 5432, database is "postgres").
- As "Database Host" enter the
- Under "Cloud Storage Settings"
- "S3 Bucket" name will be the
s3_bucketfrom terraform output of the created bucket - "S3 Region" should also match
regionfrom terraform output - "S3 Annotations" would be similar to the following with your
s3_rolefrom terraform output:
yamleks.amazonaws.com/role-arn: arn:aws:iam::<account_id>:role/paramify-mycompany-eks-sa-roleeks.amazonaws.com/role-arn: arn:aws:iam::<account_id>:role/paramify-mycompany-eks-sa-role - "S3 Bucket" name will be the
- (Recommended) Click the box for "Enable Admission Webhook"
- Lookup the container registry AWS is using for their EKS add-ons in your region from here.
- Enter the domain into "Additional Allowed Registries and Images" from the lookup, similar to the following:
yaml602401143452.dkr.ecr.us-west-2.amazonaws.com602401143452.dkr.ecr.us-west-2.amazonaws.com
Click "Continue" and wait for Preflight checks to complete
Deploy the application and wait for the "Ready" status
(Optional) Lookup the loadbalancer URL created for your service and create a DNS entry pointing to it
- Use
kubectlto get the hostname of the EKS-created load balancer (see the "EXTERNAL_IP" column):
bash$ kubectl get svc -n paramify paramify NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE paramify LoadBalancer 172.20.0.1 abcdef0123456789abcdef1234567890-1234567890.us-west-2.elb.amazonaws.com 443:32101/TCP 3m18s$ kubectl get svc -n paramify paramify NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE paramify LoadBalancer 172.20.0.1 abcdef0123456789abcdef1234567890-1234567890.us-west-2.elb.amazonaws.com 443:32101/TCP 3m18s- If using AWS Route 53 for DNS you can create as follows:
- In your domain create your DNS entry (e.g., paramify.mycompany.com)
- For "Record type" use "A" record then select "Alias"
- Under "Route traffic to" choose "Alias to Application and Classic Load Balancer", your region, then select the entry for the LB hostname that was created
TIP
The desired LB entry may start with "dualstack", such as "dualstack.abcdef0123456789abcdef1234567890-1234567890.us-west-2.elb.amazonaws.com."
- Use
Now you should be ready to access Paramify at the desired domain (e.g., https://paramify.mycompany.com) and login using one of your configured methods. Enjoy!
4. (Optional) Harden the Cluster
Once the cluster is running you can use the following steps to further harden the cluster for CIS/STIG requirements:
- Set network policies by downloading and applying the networkpolicies.yaml:
# modify this file if the application namespace is not "paramify" or DB port is not 5432
kubectl apply -f networkpolicies.yaml# modify this file if the application namespace is not "paramify" or DB port is not 5432
kubectl apply -f networkpolicies.yaml- Disable the default service account token auto-mount (replace "paramify" if it is not the app namespace)
for NS in default paramify kube-system kube-public kube-node-lease; do
kubectl patch serviceaccount default -p '{"automountServiceAccountToken": false}' -n $NS
donefor NS in default paramify kube-system kube-public kube-node-lease; do
kubectl patch serviceaccount default -p '{"automountServiceAccountToken": false}' -n $NS
done- Restrict pod security contexts (replace "paramify" if it is not the app namespace)
kubectl label --overwrite ns kube-system pod-security.kubernetes.io/enforce=privileged
kubectl label --overwrite ns kube-node-lease pod-security.kubernetes.io/enforce=baseline
kubectl label --overwrite ns kube-public pod-security.kubernetes.io/enforce=baseline
kubectl label --overwrite ns paramify pod-security.kubernetes.io/enforce=baseline
kubectl label --overwrite ns default pod-security.kubernetes.io/enforce=restrictedkubectl label --overwrite ns kube-system pod-security.kubernetes.io/enforce=privileged
kubectl label --overwrite ns kube-node-lease pod-security.kubernetes.io/enforce=baseline
kubectl label --overwrite ns kube-public pod-security.kubernetes.io/enforce=baseline
kubectl label --overwrite ns paramify pod-security.kubernetes.io/enforce=baseline
kubectl label --overwrite ns default pod-security.kubernetes.io/enforce=restricted