FusionAuth Review: The most fully-featured SSO solution for the price
Q: What did you like most about FusionAuth?
- The installation and maintenance process is straightforward, especially that they’ve provided a Helm chart that can be deployed directly to a Kubernetes cluster. When I first installed it, v1.15.8 required Elasticsearch. But in v1.16.0 and newer, Elasticsearch is optional so it’s much easier to get started especially for those with less than 10,000 users.
- The functionality is complete. It’s amazing how FusionAuth can bundle so many functionality in one software bundle AND also make it relatively easy to install. General SSO, OpenID Connect, SAML, 2FA: all the basics are covered, and more.
- Multi-tenant. This is unique with FusionAuth: with a single FusionAuth instance you can service SSO multiple groups or even multiple companies. This can dramatically reduce cost if you’re need to share resources. Or perhaps you need separate tenants for staging and development environments, you’re not required to buy a separate license for this.
- Free license available
- Support is good even without an enterprise contact (FusionAuth Forum & GitHub)
Q: What did you like least about FusionAuth?
- MariaDB isn’t yet officially supported. It’s a minor quibble and is probably irrelevant to most people, but I do wish FusionAuth would have supported this. It’s actually possible to run FusionAuth with MariaDB, just that you’ll need to be prepared to potential (current and future) issues, that you don’t have to worry if you use PostgreSQL or MySQL.
- Not open source. Again this is a minor quibble. I’d prefer if FusionAuth open sources or even made “source-available” the core parts of FusionAuth. It’d make problems much easier to debug especially if there are users willing to help debugging. For businesses getting a support contract directly from FusionAuth it’s probably not an issue.
Q: Describe your overall experience with FusionAuth?
FusionAuth has been really good and from my first experience with v1.15.8, then I upgraded twice to v1.16 then v1.17, they keep adding more features and convenience like making Elasticsearch optional. (I’m still using Elasticsearch though because I’m still migrating from previous identity provider and we have 200,000+ users to migrate, most of them are free users.) The number of free users we have is making it not cost-wise to use other identity provider products.
I have successfully integrated FusionAuth with three WordPress instances and a Rocket.Chat instance. I’m excited to complete the migration and use FusionAuth with our own custom apps.
I’m also doing consulting with social enterprises / nonprofits and when they need a login/SSO solution for their constituents/donors/volunteers, I can wholeheartedly recommend FusionAuth for them.
Q: Did you switch from another product? What product did you switch from? Why did you make the switch?
Yes, I switched from Firebase / Google Cloud Identity Platform.
- Firebase / Google Cloud Identity Platform did not support either OpenID Connect nor being a SAML Identity Provider, that we need to reliably integrate with other services such as WordPress, Rocket.Chat, and future software than we may use.
- Pricing per MAU (especially when using an external SAML) is prohibitive because most of our users are free users, and we don’t “sell” our users, so ARPU on these users is basically zero.
Q: While purchasing FusionAuth, what alternative product(s) were considered?
- Gluu
- Firebase Authentication / Google Cloud Identity Platform
- ORY/Hydra
- Amazon Cognito
- Keycloak
- FusionIAM / LemonLDAP::NG
- Okta
- JumpCloud
- OneLogin
- Auth0
Q: Why did you choose FusionAuth over these alternative product(s)?
- Free license available. FusionAuth is not open source, but startups can either deploy FusionAuth at their own server with the free license, or host with FusionAuth’s cloud with reasonable pricing (which is actually cheaper than paying your own hosting and sysadmin team to manage). The number of users you can serve is only limited by system capacity. The price/value at this stage beats all competitors I’ve reviewed. When your needs grow, you can contact FusionAuth to a get a support plan tailored to your organization. So the pricing scales very well.
- Support is good even without an enterprise contract (FusionAuth Forum & GitHub). FusionAuth technical team were willing to help diagnose my problem even I wasn’t a paying enterprise customer. If you’re planning to get a support contract, I’d say you’ll get even better support.
Preparing MariaDB
FusionAuth requires either MySQL or PostgreSQL. However, we’re currently using MariaDB 10.5 instead. This usually works operationally. However, there may be issues especially during migration (GRANT being the obvious one).
Server parameters must be configured (via AWS RDS Parameter groups):
character_set_server
=utf8mb4
collation_server
=utf8mb4_*
, preferablyutf8mb4_unicode_ci
log_bin_trust_function_creators
= 1 (it won’t make FusionAuth fail to start, but may fail migrations)
If not, FusionAuth will fail to start.
MariaDB Incompatibilities
MariaDB Incompatibilities
FusionAuth is generally incompatible with MariaDB, to ensure future compatibility, it is recommended to just use MySQL.
tenants.data
column uses JSON data type which is implemented differently in MariaDB
Installing in Kubernetes / MicroK8s using Helm Chart
There is issue #11 with FusionAuth Helm Chart that making installation not (yet) straightforward. So it is recommended to install PostgreSQL and Elasticsearch separately. Commands below assume MicroK8s, as PostgreSQL and Elasticsearch can use shared infrastructure on production.
Install in MicroK8s. Source: https://github.com/FusionAuth/charts
MariaDB
As Lovia uses MariaDB for other apps (WordPress, ERPNext), it’s also used for FusionAuth. Warning: MariaDB is not (yet?) officially supported #327, #367.
sudo microk8s helm3 repo add bitnami https://charts.bitnami.com/bitnami
sudo microk8s helm3 install mariadb bitnami/mariadb
Get the root password:
ROOT_PASSWORD=$(sudo microk8s kubectl get secret --namespace default mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 --decode)
Install MariaDB client: (as an alternative, you can also run a “mariadb-client” pod, see: helm get notes mariadb
)
sudo apt-get install mariadb-client
Port-forward and connect:
sudo microk8s kubectl port-forward svc/mariadb 3306 &
mysql -h 127.0.0.1 -uroot -p"$ROOT_PASSWORD" mysql
Create user and database: (specific GRANT
is to make it compatible with AWS RDS MariaDB)
CREATE USER fusionauth@'%' IDENTIFIED BY '*';
CREATE DATABASE fusionauth CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON fusionauth.* TO fusionauth@'%';
FLUSH PRIVILEGES;
Note: FusionAuth uses utf8mb4
character set but with utf8mb4_bin
collation.
PostgreSQL
Note: Lovia uses MariaDB for FusionAuth. This section is for informative purposes only.
https://github.com/bitnami/charts/tree/master/bitnami/postgresql
sudo microk8s helm3 repo add bitnami https://charts.bitnami.com/bitnami
sudo microk8s helm3 install postgresql bitnami/postgresql
Example output:
ceefour@amanah:~$ sudo microk8s helm3 install postgresql bitnami/postgresql
NAME: postgresql
LAST DEPLOYED: Thu Apr 16 23:54:26 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
** Please be patient while the chart is being deployed **
PostgreSQL can be accessed via port 5432 on the following DNS name from within your cluster:
postgresql.default.svc.cluster.local - Read/Write connection
To get the password for "postgres" run:
export POSTGRES_PASSWORD=$(kubectl get secret --namespace default postgresql -o jsonpath="{.data.postgresql-password}" | base64 --decode)
To connect to your database run the following command:
kubectl run postgresql-client --rm --tty -i --restart='Never' --namespace default --image docker.io/bitnami/postgresql:11.7.0-debian-10-r71 --env="PGPASSWORD=$POSTGRES_PASSWORD" --command -- psql --host postgresql -U postgres -d postgres -p 5432
To connect to your database from outside the cluster execute the following commands:
kubectl port-forward --namespace default svc/postgresql 5432:5432 &
PGPASSWORD="$POSTGRES_PASSWORD" psql --host 127.0.0.1 -U postgres -d postgres -p 5432
Create user and database: (connect first using Helm release’s notes above)
CREATE USER fusionauth PASSWORD '*';
CREATE DATABASE fusionauth
WITH OWNER fusionauth
ENCODING 'UTF8'
LC_COLLATE = 'en_US.UTF-8'
LC_CTYPE = 'en_US.UTF-8'
TEMPLATE template0;
Elasticsearch 6.x
Elastic Cloud’s Kubernetes Operator requires Support subscription. An alternative is Bitnami’s elasticsearch chart. Note: FusionAuth does not yet support Elasticsearch 7, so we provision Elasticsearch 6.x in the mean time specifically for FusionAuth.
sudo microk8s helm3 repo add bitnami https://charts.bitnami.com/bitnami
sudo microk8s helm3 install elasticsearch6 bitnami/elasticsearch --set image.tag=6,coordinating.replicas=1,master.replicas=1,master.persistence.size=1Gi,data.replicas=1,data.persistence.size=1Gi,data.resources.requests.cpu=25m,data.resources.requests.memory=384Mi
Sample output:
ceefour@amanah:~$ sudo microk8s helm3 install elasticsearch bitnami/elasticsearch
NAME: elasticsearch
LAST DEPLOYED: Thu Apr 16 23:59:40 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
-------------------------------------------------------------------------------
WARNING
Elasticsearch requires some changes in the kernel of the host machine to
work as expected. If those values are not set in the underlying operating
system, the ES containers fail to boot with ERROR messages.
More information about these requirements can be found in the links below:
https://www.elastic.co/guide/en/elasticsearch/reference/current/file-descriptors.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html
This chart uses a privileged initContainer to change those settings in the Kernel
by running: sysctl -w vm.max_map_count=262144 && sysctl -w fs.file-max=65536
** Please be patient while the chart is being deployed **
Elasticsearch can be accessed within the cluster on port 9200 at elasticsearch-elasticsearch-coordinating-only.default.svc.cluster.local
To access from outside the cluster execute the following commands:
kubectl port-forward --namespace default svc/elasticsearch-elasticsearch-coordinating-only 9200:9200 &
curl http://127.0.0.1:9200/
Note about vm.max_map_count kernel setting (not needed when using elasticsearch Helm Chart)
ElasticSearch needs more vm.max_map_count, otherwise you’ll get:
search_1 | [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
Ansible: (note: when using Bitnami’s Elasticsearch Helm chart, the required kernel values will be set accordingly)
---
- name: Setup Linux for Elasticsearch in Docker
hosts: all
become: yes
tasks:
- name: Increase vm.max_map_count for Elasticsearch
sysctl:
name: vm.max_map_count
value: '262144'
state: present
Then:
ansible-playbook -K -l local fusionauth.yml
FusionAuth
Save secret in fusionauth-secret.yaml
: (Note: Unfortunately current fusionauth helm chart does not (yet?) support valueFrom/secretKeyRef)
apiVersion: v1
kind: Secret
metadata:
name: fusionauth
data:
mariadb-password: **BASE64-ENCODED**
kubectl apply -f fusionauth-secret.yaml
Tweak values.yaml, template below: (root user and password is required at first, but can be removed later)
# Declare variables to be passed into your templates.
replicaCount: 1
elasticsearch:
# if `enabled = false` you need to set search.host
enabled: false
imageTag: 6.8.6
master:
name: master
postgresql:
# if `enabled = false` you need to set database.host
enabled: false
postgresqlUsername: localhost
postgresqlPassword: localhost
image:
repository: fusionauth/fusionauth-app
tag: latest
pullPolicy: IfNotPresent
nameOverride: ""
fullnameOverride: ""
service:
type: ClusterIP
port: 9011
database:
# if `host` is empty {{- .Release.Name -}}-postgresql will be used
protocol: mysql
host: mariadb.default.svc.cluster.local
port: 3306
# FIXME: enable TLS, set user & password
tls: false
name: fusionauth
user: fusionauth
password: localhost
root:
user: root
password: localhost
search:
protocol: http
# if `host` is empty {{- .Release.Name -}}-elasticsearch-client will be used
host: elasticsearch-elasticsearch-coordinating-only.default.svc.cluster.local
port: 9200
# FIXME: set user & password
# user: ""
# password: ""
environment:
# Database env DATABASE_USER, DATABASE_PASSWORD, DATABASE_ROOT_USER, DATABASE_ROOT_PASSWORD, DATABASE_URL will be defined in database
FUSIONAUTH_MEMORY: 256M
# FUSIONAUTH_API_KEY: test
# Its important to add /kickstart/<file> as prefix to your kickstart file else it won't work! All other files will be mounted below /kickstart/
# FUSIONAUTH_KICKSTART: /kickstart/kickstart.json
kickstart:
enabled: false
data: {}
# kickstart.json: |
# {
# "variables": {
# "defaultTenantId": "d7d09513-a3f5-401c-9685-34ab6c552453",
# "adminEmail": "[email protected]",
# "adminPassword": "password",
# },
# "apiKeys": [
# {
# "key": "bf69486b-4733-4470-a592-f1bfce7af580",
# "description": "Core API Key"
# }
# ],
# "requests": [
# {
# "method": "POST",
# "url": "/api/user/registration",
# "body": {
# "user": {
# "email": "#{adminEmail}",
# "password": "#{adminPassword}"
# },
# "registration": {
# "applicationId": "#{FUSIONAUTH_APPLICATION_ID}",
# "roles": [
# "admin"
# ]
# }
# }
# }
# ]
# }
# setup-password.html: |
# <div>Test</div>
# setup-password.txt: |
# Hallo
ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
paths: []
# Define complete path objects, will be inserted before regular paths. Can be useful for things like ALB Ingress Controller actions
extraPaths: []
hosts:
- chart-example.local
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
# resources: {}
resources:
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
limits:
memory: 400Mi
requests:
memory: 400Mi
nodeSelector: {}
tolerations: []
affinity: {}
Add fusionauth helm repo then install the chart:
sudo microk8s helm3 repo add fusionauth https://fusionauth.github.io/charts
sudo microk8s helm3 install -f values.yaml fusionauth fusionauth/fusionauth
Output:
ceefour@amanah:~/project/fusionauth-trial$ sudo microk8s helm3 install -f values.yaml fusionauth fusionauth/fusionauth
NAME: fusionauth
LAST DEPLOYED: Fri Apr 17 00:24:38 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=fusionauth,app.kubernetes.io/instance=fusionauth" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
Port forward the service and use port 9011:
kubectl port-forward svc/fusionauth 9011:9011
It will enter Maintenance Mode and you’ll need to enter MariaDB root user, root password, and the fusionauth MariaDB user’s password.
HTTPS/SSL
Prerequisities: CNAME configured, cert-manager helm chart, production_issuer, and nginx ingress helm chart properly configured. Then you can apply fusionauth-ingress.yaml
:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: fusionauth-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
# REQUIRES helm cert-manager
tls:
- hosts:
- fusionauth.lovia.life
secretName: fusionauth-tls
rules:
- host: fusionauth.lovia.life
http:
paths:
- backend:
serviceName: fusionauth
servicePort: 9011
It will take some time before the TLS certificate is generated:
kubectl describe certificate fusionauth-tls
System/Default Settings
Email:
- Configure SMTP (use SES) in Tenants > Default > Email. Use port 587 instead of 25 (confirmed to work in DigitalOcean Kubernetes).
- Configure Email Templates: From Email, From Name, HTML (URL & signature), Text (URL & signature)
Settings:
- System > Reports > Report timezone
Troubleshooting
Reference: https://fusionauth.io/docs/v1/tech/troubleshooting
Usual issue: not enough memory request & limit
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pulled 23m kubelet, amanah Container image "darthcabs/tiny-tools:1" already present on machine
Normal Scheduled 23m default-scheduler Successfully assigned default/fusionauth-568f4d986-54g8b to amanah
Normal Created 23m kubelet, amanah Created container wait-for-db
Normal Pulled 23m kubelet, amanah Container image "darthcabs/tiny-tools:1" already present on machine
Normal Created 23m kubelet, amanah Created container wait-for-search
Normal Started 23m kubelet, amanah Started container wait-for-db
Normal Started 23m kubelet, amanah Started container wait-for-search
Normal Pulling 23m kubelet, amanah Pulling image "fusionauth/fusionauth-app:latest"
Normal Pulled 23m kubelet, amanah Successfully pulled image "fusionauth/fusionauth-app:latest"
Normal Killing 22m kubelet, amanah Container fusionauth failed liveness probe, will be restarted
Warning Unhealthy 22m kubelet, amanah Liveness probe failed: Get http://10.1.87.43:9011/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Normal Created 22m (x2 over 23m) kubelet, amanah Created container fusionauth
Normal Pulled 22m kubelet, amanah Container image "fusionauth/fusionauth-app:latest" already present on machine
Normal Started 22m (x2 over 23m) kubelet, amanah Started container fusionauth
Warning Unhealthy 22m (x4 over 22m) kubelet, amanah Readiness probe failed: Get http://10.1.87.43:9011/: dial tcp 10.1.87.43:9011: connect: connection refused
Warning Unhealthy 22m (x4 over 22m) kubelet, amanah Liveness probe failed: Get http://10.1.87.43:9011/: dial tcp 10.1.87.43:9011: connect: connection refused
Warning Unhealthy 8m13s (x9 over 22m) kubelet, amanah Readiness probe failed: Get http://10.1.87.43:9011/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning BackOff 3m12s (x76 over 20m) kubelet, amanah Back-off restarting failed container
ceefour@amanah:~/project/fusionauth-trial$ kubectl logs -f fusionauth-574fb9dfbc-mxtvw
16-Apr-2020 18:03:12.530 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
16-Apr-2020 18:03:24.229 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-9011"]
16-Apr-2020 18:03:25.529 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
16-Apr-2020 18:03:26.832 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-jsse-nio-9013"]
Sample output of “kubectl describe po $POD_NAME”
Last State: Terminated
Reason: Error
Exit Code: 143
Started: Fri, 17 Apr 2020 02:07:53 +0700
Finished: Fri, 17 Apr 2020 02:08:23 +0700
After getting inside by doing:
sudo microk8s kubectl exec -it $POD_NAME -- /bin/bash
the FusionAuth files are in /usr/local/fusionauth
Currently it seems root user and password are required, otherwise:
Apr 18, 2020 9:51:32.803 AM INFO io.fusionauth.api.configuration.PropertiesFileFusionAuthConfiguration - FusionAuth Runtime Mode [Production]
Apr 18, 2020 9:53:03.714 AM INFO io.fusionauth.api.configuration.PropertiesFileFusionAuthConfiguration - Loading FusionAuth configuration file [/usr/local/fusionauth/fusionauth-app/apache-tomcat/../../config/fusionauth.properties]
Apr 18, 2020 9:53:03.716 AM INFO io.fusionauth.api.configuration.PropertiesFileFusionAuthConfiguration - Dynamically set property [fusionauth-app.public-url] set to [http://10.1.87.193:9011]
Apr 18, 2020 9:53:03.716 AM INFO io.fusionauth.api.configuration.PropertiesFileFusionAuthConfiguration - FusionAuth Runtime Mode [Production]
Apr 18, 2020 9:53:04.180 AM INFO io.fusionauth.app.maintenance.FusionAuthMaintenanceModeWorkflow - Determine database status : ORDINARY_USER_CANNOT_CONNECT [Access denied for user 'fusionauth'@'10.1.87.1' (using password: YES)]
Apr 18, 2020 9:53:04.183 AM INFO org.primeframework.mvc.servlet.PrimeServletContextListener - Initializing Prime
Apr 18, 2020 9:53:04.185 AM INFO io.fusionauth.app.maintenance.guice.FusionAuthMaintenanceModeModule -
---------------------------------------------------------------------------------------------------------
--------------------------------------- Entering Maintenance Mode ---------------------------------------
---------------------------------------------------------------------------------------------------------
Apr 18, 2020 9:53:04.288 AM INFO io.fusionauth.api.configuration.PropertiesFileFusionAuthConfiguration - Loading FusionAuth configuration file [/usr/local/fusionauth/fusionauth-app/apache-tomcat/../../config/fusionauth.properties]
Apr 18, 2020 9:53:04.289 AM INFO io.fusionauth.api.configuration.PropertiesFileFusionAuthConfiguration - Dynamically set property [fusionauth-app.public-url] set to [http://10.1.87.193:9011]
Apr 18, 2020 9:53:04.289 AM INFO io.fusionauth.api.configuration.PropertiesFileFusionAuthConfiguration - FusionAuth Runtime Mode [Production]
Apr 18, 2020 9:53:04.293 AM INFO com.inversoft.maintenance.MaintenanceModePoller - Poller started to Wait for configuration to be completed.
18-Apr-2020 09:53:04.401 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-9011"]
18-Apr-2020 09:53:04.429 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-jsse-nio-9013"]
18-Apr-2020 09:53:04.436 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-9019"]
18-Apr-2020 09:53:04.442 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 104675 ms
CloudFront CDN
https://chat.lovia.life is fronted by CloudFront CDN d363egvcze92jw.cloudfront.net.
is fronted by CloudFront CDN d363egvcze92jw.cloudfront.net.
Appendix: Creating Helm Charts
Create your first Helm chart – Bitnami
FusionAuth Setup Wizard
After installing FusionAuth + Elasticsearch + PostgreSQL/MySQL (MariaDB is not (yet?) officially supported #327, #367) you’ll be presented with FusionAuth Setup Wizard.
FusionAuth provides the following fields by default. FusionAuth provides two ways for custom fields: user.data and registration.data. Either email or username is required. User ID is automatically generated by FusionAuth and is always a UUID.
Email/SMTP
SMTP must be set up so FusionAuth can send emails.
See: https://fusionauth.io/docs/v1/tech/email-templates/configure-email
Getting Started
Known Issues
- In Users > (choose user) > Manage : Last login is “-“, even if Session tab shows that user has logged in using OAuth OpenID Connect with that specific application.
- In Users > (choose user) > Manage > Registrations. After adding a registration, then wait about 1-3 minutes, refresh, the registration is gone.
- In Users > (choose user) > Manage > Registrations: Last login is “-“, even if Session show that user has logged in.
- In Users > Applications > (choose application) > Manage Roles: After adding a role, then wait about 1-3 minutes, refresh, the role is “gone”. However, the role is actually “still there”, just not displayed. We can check this by adding a new role with the same name, which will error with message “Exists”.
Reported as https://github.com/FusionAuth/fusionauth-issues/issues/563
Upgrading FusionAuth
Preflight Checklist
Preflight checklist:
SHOW VARIABLES LIKE 'log_%'
and make surelog_bin_trust_function_creators
is ON.- Check
fusionauth.version
table and make sure the migration version there is not far behind the current installed version. For example, in FusionAuth v1.24.0, the migration version was 1.23.0. In Fusion v1.25.0, the migration version was 1.25.0. That means, if you are running FusionAuth v1.25.0 but the migration version is still 1.23.0, you must migrate the database first. - Create an (RDS) snapshot or backup using mysqldump / mariadbdump.
- Ensure you know whether you’re running in
development
orproduction
mode. - If you want to run in production mode but apply database migrations automatically, in Task Definition, set environment
FUSIONAUTH_APP_SILENT_MODE=true
.
Manual database migration:
If Deployed using Docker AWS ECS / Fargate
How to upgrade:
- In Task Definition, create a new revision.
- Check fusionauth/fusionauth-app Docker tags. Set the image version to next minor version but latest patch version. Save the Task Definition.
- In ECS/Fargate, edit the Service. Change to latest Task Definition revision. Save to launch the new container version.
- Wait until the new version’s Task is deployed successfully.
- If you set
FUSIONAUTH_APP_SILENT_MODE=true
, or in development mode database migrations will be applied automatically. Otherwise if you’re in production runtime mode and did not enable silent mode, see below on how to apply database migrations. - In there is a newer minor version, repeat from step 1.
- (If still in
development
mode:) In Task Definition, setFUSIONAUTH_APP_RUNTIME_MODE=production
, then edit the service to latest Task Definition.
Note: You cannot run multiple nodes having mixed modes (development vs production). So you must stop all development nodes before switching to production mode, and vice versa.
If Deployed to Kubernetes and using “production” runtime mode
In lovia/lovia-devops Git repository.
- Run:
helm repo update
- Change
values.yaml
and set image.tag to desired stable version. - Run:
helm upgrade fusionauth fusionauth/fusionauth -f values.yaml
- Monitor logs:
kubectl logs -f POD_NAME
- Since we’re using production runtime mode, FusionAuth will not apply migrations automatically. So we need to apply migrations out-of-band.
Apply Database Migrations Manually
Reference: FusionAuth Database Migrations
Download the database migration scripts from FusionAuth, filename is fusionauth-database-schema-*.zip.
You need to apply all migrations after the version mentioned in the fusionauth.version
table. Make sure to run each migration script only once, as the scripts are not idempotent. Important: If you use DataGrip, make sure that when it gets to “UPDATE without where” statement, you do “Execute”.
Troubleshooting: Database migration for FusionAuth 1.19.0 on AWS RDS MySQL:
fusionauth> CREATE FUNCTION generate_id()
RETURNS BINARY(16)
NOT DETERMINISTIC
NO SQL
BEGIN
RETURN SUBSTR(CONCAT(MD5(RAND()), MD5(RAND())), 3, 16);
END
[2020-09-12 15:39:47] [HY000][1419] You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
When using RDS you have to create a new RDS parameter group (this can be done from the RDS dashboard on the web), set log_bin_trust_function_creators
to 1 (as opposed to <engine-default>
, save the parameter group.
Then modify your RDS instance to use this parameter group, save, and reboot your RDS instance and it should work. You can read more here: https://forums.aws.amazon.com/message.jspa?messageID=183618, and http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.html.
With RDS MariaDB and no root credentials, you may get:
java.lang.IllegalStateException: Unable to capture database lock. This indicates that the database either doesn’t support locks or is misconfigured.
Cause is issue #849.
Solution: Migrate the MariaDB databases manually.