1. Home
  2. Docs
  3. Infrastructure
  4. FusionAuth

FusionAuth

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_serverutf8mb4
  • collation_serverutf8mb4_*, preferably utf8mb4_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.

  1. 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:

  1. Configure SMTP (use SES) in Tenants > Default > Email. Use port 587 instead of 25 (confirmed to work in DigitalOcean Kubernetes).
  2. Configure Email Templates: From Email, From Name, HTML (URL & signature), Text (URL & signature)

Settings:

  1. 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

  1. 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.
  2. In Users > (choose user) > Manage > Registrations. After adding a registration, then wait about 1-3 minutes, refresh, the registration is gone.
  3. In Users > (choose user) > Manage > Registrations: Last login is “-“, even if Session show that user has logged in.
  4. 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:

  1. SHOW VARIABLES LIKE 'log_%' and make sure log_bin_trust_function_creators is ON.
  2. 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.
  3. Create an (RDS) snapshot or backup using mysqldump / mariadbdump.
  4. Ensure you know whether you’re running in development or production mode.
  5. 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:

  1. In Task Definition, create a new revision.
  2. Check fusionauth/fusionauth-app Docker tags. Set the image version to next minor version but latest patch version. Save the Task Definition.
  3. In ECS/Fargate, edit the Service. Change to latest Task Definition revision. Save to launch the new container version.
  4. Wait until the new version’s Task is deployed successfully.
  5. 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.
  6. In there is a newer minor version, repeat from step 1.
  7. (If still in development mode:) In Task Definition, set FUSIONAUTH_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.

  1. Run: helm repo update
  2. Change values.yaml and set image.tag to desired stable version.
  3. Run: helm upgrade fusionauth fusionauth/fusionauth -f values.yaml
  4. Monitor logs: kubectl logs -f POD_NAME
  5. 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)

Solution/Workaround:

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.

Articles

How can we help?