Sort by Topics, Resources
Clear
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Salto for

Okta

Articles

SHARE

Terraform and Salto: two paths to effective Okta configuration management

Gil Hoffer

March 21, 2024

10

min read

At first glance, Salto and Terraform appear to be similar solutions for managing Okta configuration — both aim to streamline operations and ensure consistency. However, a deeper look reveals fundamental differences in their approaches and core strengths.

In this article, we explore those differences and main considerations when choosing between Salto and the Terraform Okta provider for managing your configuration.

Experience the Ease & Confidence of NetSuite Customizations with Salto

Automate the way you migrate Jira configurations from sandbox to production

STAY UP TO DATE

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

What is Terraform?

Terraform by HashiCorp is an infrastructure-as-code tool that allows teams to define and provision infrastructure using a high-level declarative configuration language called HCL. It enables developers and infrastructure teams to automate the deployment, management, and scaling of various cloud services, helping organizations maintain a consistent workflow across multiple providers and multiple environments. Terraform, with its focus on infrastructure as code, plays a crucial role in DevOps practices by streamlining the deployment process and fostering collaboration among development and operations teams.

Terraform has many providers, including one for Okta, enabling it to manage Okta configuration as code.

What is Salto?

Salto is a DevOps platform for managing the configuration of SaaS applications. It translates configurations into a high-level declarative configuration language called NaCl (a dialect of HCL). Salto allows administrators and developers to streamline configuration change management using DevOps processes and tools such as version control, automation, CI/CD, and backup.

Salto supports various IT and business applications, including Salesforce, Jira, NetSuite, Zendesk, and Okta.

How do Salto and Terraform compare?

For the sake of this comparison, let’s consider a 3-environments-based release pipeline with configuration changes flowing from dev to uat to production. Changes are first implemented in dev then deployed to uat for acceptance testing, and finally released in batches from uat to production.

With Terraform, those configuration changes would be manually codified (once + variable definitions if needed), committed to Git (using a chosen branching strategy), and deployed to the target environments using the Terraform CLI, potentially from a CI/CD pipeline. This assumes that you already have an up-to-date accurate representation of your environments in HCL and that all of your environments are identical from a configuration standpoint.

💡 It’s possible to generate HCL code (using Terraformer or a similar tool) and import such resources to Terraform. However, that process can become hard to manage continuously at scale.

With Salto, you would develop the changes directly in Okta’s Admin Console for dev fetch those changes to Salto, and use Salto to optionally commit them to Git as well as deploy them to the higher environments. This assumes that all environments are connected to Salto and are being fetched periodically.

💡 Fetch is a core Salto concept that automatically generates and updates the code representation of a service from its current implementation. Typically it runs on a scheduler and can be intermixed with edits done to the code representation and deployment operations.


If you want to see how Salto works in more detail, check out this video:


Your team’s skill set

As you can see, Salto and Terraform require a very different set of skills.

Effective use of Terraform requires deep knowledge of the tool, typically found within DevOps/Infrastructure teams that manage your AWS, GCP, or Azure configurations. Changes are coded directly in HCL and follow standard development practices. To leverage Terraform for Okta configuration management, your team members will need to be experts in these three areas:

  • Okta
  • Terraform (and Git)
  • Okta’s representation in HCL

To develop a configuration change, one will need to intimately know the representation of that change in HCL and how to mimic in HCL different operations that they would typically perform in the Okta Admin Console.

For example, this is a sample HCL file for a SAML App (source):


resource "okta_app_saml" "test" {
  label                     = "testAcc_replace_with_uuid"
  sso_url                   = "http://google.com"
  recipient                 = "http://here.com"
  destination               = "http://its-about-the-journey.com"
  audience                  = "http://audience.com"
  subject_name_id_template  = "$${user.userName}"
  subject_name_id_format    = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
  response_signed           = true
  signature_algorithm       = "RSA_SHA256"
  digest_algorithm          = "SHA256"
  honor_force_authn         = false
  authn_context_class_ref   = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
  single_logout_issuer      = "https://dunshire.okta.com"
  single_logout_url         = "https://dunshire.okta.com/logout"
  single_logout_certificate = "MIIFnDCCA4QCCQDBSLbiON2T1zANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxDjAMBgNV\r\nBAgMBU1haW5lMRAwDgYDVQQHDAdDYXJpYm91MRcwFQYDVQQKDA5Tbm93bWFrZXJzIEluYzEUMBIG\r\nA1UECwwLRW5naW5lZXJpbmcxDTALBgNVBAMMBFNub3cxIDAeBgkqhkiG9w0BCQEWEWVtYWlsQGV4\r\nYW1wbGUuY29tMB4XDTIwMTIwMzIyNDY0M1oXDTMwMTIwMTIyNDY0M1owgY8xCzAJBgNVBAYTAlVT\r\nMQ4wDAYDVQQIDAVNYWluZTEQMA4GA1UEBwwHQ2FyaWJvdTEXMBUGA1UECgwOU25vd21ha2VycyBJ\r\nbmMxFDASBgNVBAsMC0VuZ2luZWVyaW5nMQ0wCwYDVQQDDARTbm93MSAwHgYJKoZIhvcNAQkBFhFl\r\nbWFpbEBleGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANMmWDjXPdoa\r\nPyzIENqeY9njLan2FqCbQPSestWUUcb6NhDsJVGSQ7XR+ozQA5TaJzbP7cAJUj8vCcbqMZsgOQAu\r\nO/pzYyQEKptLmrGvPn7xkJ1A1xLkp2NY18cpDTeUPueJUoidZ9EJwEuyUZIktzxNNU1pA1lGijiu\r\n2XNxs9d9JR/hm3tCu9Im8qLVB4JtX80YUa6QtlRjWR/H8a373AYCOASdoB3c57fIPD8ATDNy2w/c\r\nfCVGiyKDMFB+GA/WTsZpOP3iohRp8ltAncSuzypcztb2iE+jijtTsiC9kUA2abAJqqpoCJubNShi\r\nVff4822czpziS44MV2guC9wANi8u3Uyl5MKsU95j01jzadKRP5S+2f0K+n8n4UoV9fnqZFyuGAKd\r\nCJi9K6NlSAP+TgPe/JP9FOSuxQOHWJfmdLHdJD+evoKi9E55sr5lRFK0xU1Fj5Ld7zjC0pXPhtJf\r\nsgjEZzD433AsHnRzvRT1KSNCPkLYomznZo5n9rWYgCQ8HcytlQDTesmKE+s05E/VSWNtH84XdDrt\r\nieXwfwhHfaABSu+WjZYxi9CXdFCSvXhsgufUcK4FbYAHl/ga/cJxZc52yFC7Pcq0u9O2BSCjYPdQ\r\nDAHs9dhT1RhwVLM8RmoAzgxyyzau0gxnAlgSBD9FMW6dXqIHIp8yAAg9cRXhYRTNAgMBAAEwDQYJ\r\nKoZIhvcNAQELBQADggIBADofEC1SvG8qa7pmKCjB/E9Sxhk3mvUO9Gq43xzwVb721Ng3VYf4vGU3\r\nwLUwJeLt0wggnj26NJweN5T3q9T8UMxZhHSWvttEU3+S1nArRB0beti716HSlOCDx4wTmBu/D1MG\r\nt/kZYFJw+zuzvAcbYct2pK69AQhD8xAIbQvqADJI7cCK3yRry+aWtppc58P81KYabUlCfFXfhJ9E\r\nP72ffN4jVHpX3lxxYh7FKAdiKbY2FYzjsc7RdgKI1R3iAAZUCGBTvezNzaetGzTUjjl/g1tcVYij\r\nltH9ZOQBPlUMI88lxUxqgRTerpPmAJH00CACx4JFiZrweLM1trZyy06wNDQgLrqHr3EOagBF/O2h\r\nhfTehNdVr6iq3YhKWBo4/+RL0RCzHMh4u86VbDDnDn4Y6HzLuyIAtBFoikoKM6UHTOa0Pqv2bBr5\r\nwbkRkVUxl9yJJw/HmTCdfnsM9dTOJUKzEglnGF2184Gg+qJDZB6fSf0EAO1F6sTqiSswl+uHQZiy\r\nDaZzyU7Gg5seKOZ20zTRaX3Ihj9Zij/ORnrARE7eM/usKMECp+7syUwAUKxDCZkGiUdskmOhhBGL\r\nJtbyK3F2UvoJoLsm3pIcvMak9KwMjSTGJB47ABUP1+w+zGcNk0D5Co3IJ6QekiLfWJyQ+kKsWLKt\r\nzOYQQatrnBagM7MI2/T4\r\n"

  attribute_statements {
    type         = "GROUP"
    name         = "groups"
    filter_type  = "REGEX"
    filter_value = ".*"
  }
}

data "okta_app_signon_policy" "test" {
  app_id = okta_app_saml.test.id
}

resource "okta_user" "test" {
  count      = 5
  first_name = "TestAcc"
  last_name  = "Smith"
  login      = "testAcc_${count.index}@example.com"
  email      = "testAcc_${count.index}@example.com"
}

resource "okta_group" "this" {
  count       = 5
  name        = "testAcc_${count.index}"
  description = "testAcc_${count.index}"
}

resource "okta_user_type" "test" {
  name         = "testAcc_replace_with_uuid"
  display_name = "Terraform Acceptance Test User Type Updated"
  description  = "Terraform Acceptance Test User Type Updated"
}

resource "okta_network_zone" "test" {
  name     = "testAcc_replace_with_uuid"
  type     = "IP"
  gateways = ["1.2.3.4/24", "2.3.4.5-2.3.4.15"]
  proxies  = ["2.2.3.4/24", "3.3.4.5-3.3.4.15"]
  status   = "ACTIVE"
}

data "okta_user_type" "default" {
  name = "user"
}

resource "okta_policy_device_assurance_android" "test" {
  name       = "test"
  os_version = "12"
  jailbreak  = false
}

resource "okta_app_signon_policy_rule" "test" {
  name                 = "testAcc_replace_with_uuid_updated"
  policy_id            = data.okta_app_signon_policy.test.id
  access               = "ALLOW"
  custom_expression    = "user.status == \"ACTIVE\""
  device_is_managed    = false
  device_is_registered = true
  factor_mode          = "2FA"
  groups_excluded = [
    okta_group.this[2].id,
    okta_group.this[3].id,
    okta_group.this[4].id
  ]
  groups_included = [
    okta_group.this[0].id,
    okta_group.this[1].id
  ]
  device_assurances_included = [
    okta_policy_device_assurance_android.test.id
  ]
  network_connection = "ZONE"
  network_includes = [
    okta_network_zone.test.id
  ]
  platform_include {
    os_type = "ANDROID"
    type    = "MOBILE"
  }
  platform_include {
    os_type = "IOS"
    type    = "MOBILE"
  }
  platform_include {
    os_type = "MACOS"
    type    = "DESKTOP"
  }
  # FIXME Okta API for /api/v1/policies/{policyId}/rules/{ruleId}
  # is not returning os_expression even when it has been set throwing off the TF state.
  #  platform_include {
  #    os_expression = ".*"
  #    os_type = "OTHER"
  #    type    = "DESKTOP"
  #  }
  #  platform_include {
  #    os_expression = ".*"
  #    os_type = "OTHER"
  #    type    = "MOBILE"
  #  }
  risk_score = "MEDIUM"
  platform_include {
    os_type = "WINDOWS"
    type    = "DESKTOP"
  }
  platform_include {
    os_type = "CHROMEOS"
    type    = "DESKTOP"
  }
  priority                    = 98
  re_authentication_frequency = "PT43800H"
  inactivity_period           = "PT2H"
  type                        = "ASSURANCE"
  user_types_excluded = [
    okta_user_type.test.id
  ]
  user_types_included = [
    data.okta_user_type.default.id
  ]
  users_excluded = [
    okta_user.test[2].id,
    okta_user.test[3].id,
    okta_user.test[4].id
  ]
  users_included = [
    okta_user.test[0].id,
    okta_user.test[1].id
  ]
  constraints = [
    jsonencode({
      "knowledge" : {
        "reauthenticateIn" : "PT2H",
        "types" : ["password"]
      },
      "possession" : {
        "deviceBound" : "REQUIRED"
      }
    }),
    jsonencode({
      "possession" : {
        "deviceBound" : "REQUIRED",
        "hardwareProtection" : "REQUIRED",
        "userPresence" : "OPTIONAL"
      }
    })
  ]
}


If your team has expertise in all of those areas and can comfortably develop configuration changes manually as code, then Terraform might be a great fit.

Salto doesn’t rely on coding directly in a configuration language. Instead, Okta admins can keep developing changes in the dev environment using the Okta Admin Console, then Salto would fetch those changes and translate them to code. There are two options for deploying those changes to higher environments: either using Salto’s UI or with standard automated tools (such as Git and CI/CD pipelines) that can be integrated with Salto.

While Salto relies on a code-based representation of your configuration, it doesn’t require administrators to be proficient in that representation or to be able to modify it as code. If your IAM team has Okta expertise without a deep understanding of Terraform and infrastructure automation, Salto would be a better fit.

❗ What does it look like in terms of core strength and skill set in your team? If it’s mostly Okta and IAM expertise, then Salto would be a better fit. Alternatively, if the team deeply understands Terraform and infrastructure automation, then Terraform would fit well.

Immutability

One of Terraform’s assumptions is that changes are always done using code and never directly in the service itself. This assumption makes perfect sense when managing your infrastructure provider (such as AWS), but things become tricky when you need to manage a rich no/low-code UI-based solution like Okta. It's common for a team to have changes done in the service itself when some team members are Okta experts who are more comfortable working with the Okta UI rather than in code (as mentioned above). Another case is if changes (hotfixes) done directly in production. While changes normally shouldn’t be done directly in production, there are some cases where it makes sense.

With Terraform, a direct service change would create a discrepancy between the Terraform state file and the real state of the service—and would require careful specific handling. These changes may be discovered right before an attempt to deploy a change and can cause significant delays.

With Salto, such changes will be detected automatically. Detected changes in lower environments are funneling into the same release pipeline as changes done through code editing, in a streamlined manner. When changes are detected in production, the user can decide whether they should be reverted or accepted (and back-promoted to lower environments).

Configuration deployment modes

Terraform deployment mode is simple and follows a standard development process: develop the code and deploy it (so it’s always “source driven”).

Salto supports multiple deployment modes:

  1. Tenant-to-tenant compare and deploy: Compare the configurations of two tenants and deploy changes between them
  2. Change-based deployments: Detect changes done to a tenant in a certain time frame and deploy them (or a subset of them) to another instance
  3. Source-driven
  4. Restore: Compare the current version to a historical point in time and selectively deploy historical configuration elements as needed

Supported applications

While this post is focused on Okta, it’s worth mentioning that both solutions support many other applications.

Terraform has thousands of providers and is typically focused on infrastructure solutions such as AWS, GCP, and Azure. Salto supports multiple applications as well, with a focus on IT and business applications (Jira, Salesforce, Zendesk, Okta, Google Workspace, NetSuite, and more).

One thing to consider here is if your Okta implementation needs to be synergetic with other enterprise applications you’re using.

User interface

Terraform is great if you are comfortable working in a CLI, and potentially in an IDE. There are also commercial offerings such as Terraform Cloud, Env0, and Spacelift that add a UI to orchestrate changes already done in code.

Salto can be used from a CLI and also has a powerful web-based UI that enables your team to:

  • Explore and understand your Okta configuration and dependencies in it
  • Understand differences between multiple tenants (a tenant diff tool)

Packaging

Terraform is licensed under the Business Source License and has various commercial SaaS offerings on top that provide a managed service (such as Terraform Cloud, Env0, Spacelift, etc.)

Salto is based on an open-source project (licensed under Apache 2.0 license). Salto’s SaaS offering has two tiers: a free-for-life tier for configuration visibility and a commercial tier that enables deployments, configuration backup, monitoring, and many more features.

To summarize this comparison, choosing between Salto and Terraform for managing your Okta configuration largely depends on your team's technical expertise and the flexibility you need in your change management process. By considering the strengths and limitations of each tool, you can make an informed decision that best suits your operational requirements and strategic goals.

STAY UP TO DATE

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Talk to one of our experts

Explore Salto for managing your Okta configuration

Learn more

WRITTEN BY OUR EXPERT

Gil Hoffer

Co-Founder, CTO

Gil is co-founder and CTO at Salto. He started programming at the age of 6 (Basic on Commodore64), and has been around computers ever since. Loves to build stuff—products, systems, teams, and organizations. Ex-VP Engineering at Oracle, VP R&D at Ravello Systems, IDF’s Unit 8200.

Sort by Topics, Resources
Clear
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Salto for

Okta

SHARE

Terraform and Salto: two paths to effective Okta configuration management

Gil Hoffer

March 21, 2024

10

min read

At first glance, Salto and Terraform appear to be similar solutions for managing Okta configuration — both aim to streamline operations and ensure consistency. However, a deeper look reveals fundamental differences in their approaches and core strengths.

In this article, we explore those differences and main considerations when choosing between Salto and the Terraform Okta provider for managing your configuration.

What if Zendesk was 4x less work?

Request a Demo Get started with Salto

What is Terraform?

Terraform by HashiCorp is an infrastructure-as-code tool that allows teams to define and provision infrastructure using a high-level declarative configuration language called HCL. It enables developers and infrastructure teams to automate the deployment, management, and scaling of various cloud services, helping organizations maintain a consistent workflow across multiple providers and multiple environments. Terraform, with its focus on infrastructure as code, plays a crucial role in DevOps practices by streamlining the deployment process and fostering collaboration among development and operations teams.

Terraform has many providers, including one for Okta, enabling it to manage Okta configuration as code.

What is Salto?

Salto is a DevOps platform for managing the configuration of SaaS applications. It translates configurations into a high-level declarative configuration language called NaCl (a dialect of HCL). Salto allows administrators and developers to streamline configuration change management using DevOps processes and tools such as version control, automation, CI/CD, and backup.

Salto supports various IT and business applications, including Salesforce, Jira, NetSuite, Zendesk, and Okta.

How do Salto and Terraform compare?

For the sake of this comparison, let’s consider a 3-environments-based release pipeline with configuration changes flowing from dev to uat to production. Changes are first implemented in dev then deployed to uat for acceptance testing, and finally released in batches from uat to production.

With Terraform, those configuration changes would be manually codified (once + variable definitions if needed), committed to Git (using a chosen branching strategy), and deployed to the target environments using the Terraform CLI, potentially from a CI/CD pipeline. This assumes that you already have an up-to-date accurate representation of your environments in HCL and that all of your environments are identical from a configuration standpoint.

💡 It’s possible to generate HCL code (using Terraformer or a similar tool) and import such resources to Terraform. However, that process can become hard to manage continuously at scale.

With Salto, you would develop the changes directly in Okta’s Admin Console for dev fetch those changes to Salto, and use Salto to optionally commit them to Git as well as deploy them to the higher environments. This assumes that all environments are connected to Salto and are being fetched periodically.

💡 Fetch is a core Salto concept that automatically generates and updates the code representation of a service from its current implementation. Typically it runs on a scheduler and can be intermixed with edits done to the code representation and deployment operations.


If you want to see how Salto works in more detail, check out this video:


Your team’s skill set

As you can see, Salto and Terraform require a very different set of skills.

Effective use of Terraform requires deep knowledge of the tool, typically found within DevOps/Infrastructure teams that manage your AWS, GCP, or Azure configurations. Changes are coded directly in HCL and follow standard development practices. To leverage Terraform for Okta configuration management, your team members will need to be experts in these three areas:

  • Okta
  • Terraform (and Git)
  • Okta’s representation in HCL

To develop a configuration change, one will need to intimately know the representation of that change in HCL and how to mimic in HCL different operations that they would typically perform in the Okta Admin Console.

For example, this is a sample HCL file for a SAML App (source):


resource "okta_app_saml" "test" {
  label                     = "testAcc_replace_with_uuid"
  sso_url                   = "http://google.com"
  recipient                 = "http://here.com"
  destination               = "http://its-about-the-journey.com"
  audience                  = "http://audience.com"
  subject_name_id_template  = "$${user.userName}"
  subject_name_id_format    = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
  response_signed           = true
  signature_algorithm       = "RSA_SHA256"
  digest_algorithm          = "SHA256"
  honor_force_authn         = false
  authn_context_class_ref   = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
  single_logout_issuer      = "https://dunshire.okta.com"
  single_logout_url         = "https://dunshire.okta.com/logout"
  single_logout_certificate = "MIIFnDCCA4QCCQDBSLbiON2T1zANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxDjAMBgNV\r\nBAgMBU1haW5lMRAwDgYDVQQHDAdDYXJpYm91MRcwFQYDVQQKDA5Tbm93bWFrZXJzIEluYzEUMBIG\r\nA1UECwwLRW5naW5lZXJpbmcxDTALBgNVBAMMBFNub3cxIDAeBgkqhkiG9w0BCQEWEWVtYWlsQGV4\r\nYW1wbGUuY29tMB4XDTIwMTIwMzIyNDY0M1oXDTMwMTIwMTIyNDY0M1owgY8xCzAJBgNVBAYTAlVT\r\nMQ4wDAYDVQQIDAVNYWluZTEQMA4GA1UEBwwHQ2FyaWJvdTEXMBUGA1UECgwOU25vd21ha2VycyBJ\r\nbmMxFDASBgNVBAsMC0VuZ2luZWVyaW5nMQ0wCwYDVQQDDARTbm93MSAwHgYJKoZIhvcNAQkBFhFl\r\nbWFpbEBleGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANMmWDjXPdoa\r\nPyzIENqeY9njLan2FqCbQPSestWUUcb6NhDsJVGSQ7XR+ozQA5TaJzbP7cAJUj8vCcbqMZsgOQAu\r\nO/pzYyQEKptLmrGvPn7xkJ1A1xLkp2NY18cpDTeUPueJUoidZ9EJwEuyUZIktzxNNU1pA1lGijiu\r\n2XNxs9d9JR/hm3tCu9Im8qLVB4JtX80YUa6QtlRjWR/H8a373AYCOASdoB3c57fIPD8ATDNy2w/c\r\nfCVGiyKDMFB+GA/WTsZpOP3iohRp8ltAncSuzypcztb2iE+jijtTsiC9kUA2abAJqqpoCJubNShi\r\nVff4822czpziS44MV2guC9wANi8u3Uyl5MKsU95j01jzadKRP5S+2f0K+n8n4UoV9fnqZFyuGAKd\r\nCJi9K6NlSAP+TgPe/JP9FOSuxQOHWJfmdLHdJD+evoKi9E55sr5lRFK0xU1Fj5Ld7zjC0pXPhtJf\r\nsgjEZzD433AsHnRzvRT1KSNCPkLYomznZo5n9rWYgCQ8HcytlQDTesmKE+s05E/VSWNtH84XdDrt\r\nieXwfwhHfaABSu+WjZYxi9CXdFCSvXhsgufUcK4FbYAHl/ga/cJxZc52yFC7Pcq0u9O2BSCjYPdQ\r\nDAHs9dhT1RhwVLM8RmoAzgxyyzau0gxnAlgSBD9FMW6dXqIHIp8yAAg9cRXhYRTNAgMBAAEwDQYJ\r\nKoZIhvcNAQELBQADggIBADofEC1SvG8qa7pmKCjB/E9Sxhk3mvUO9Gq43xzwVb721Ng3VYf4vGU3\r\nwLUwJeLt0wggnj26NJweN5T3q9T8UMxZhHSWvttEU3+S1nArRB0beti716HSlOCDx4wTmBu/D1MG\r\nt/kZYFJw+zuzvAcbYct2pK69AQhD8xAIbQvqADJI7cCK3yRry+aWtppc58P81KYabUlCfFXfhJ9E\r\nP72ffN4jVHpX3lxxYh7FKAdiKbY2FYzjsc7RdgKI1R3iAAZUCGBTvezNzaetGzTUjjl/g1tcVYij\r\nltH9ZOQBPlUMI88lxUxqgRTerpPmAJH00CACx4JFiZrweLM1trZyy06wNDQgLrqHr3EOagBF/O2h\r\nhfTehNdVr6iq3YhKWBo4/+RL0RCzHMh4u86VbDDnDn4Y6HzLuyIAtBFoikoKM6UHTOa0Pqv2bBr5\r\nwbkRkVUxl9yJJw/HmTCdfnsM9dTOJUKzEglnGF2184Gg+qJDZB6fSf0EAO1F6sTqiSswl+uHQZiy\r\nDaZzyU7Gg5seKOZ20zTRaX3Ihj9Zij/ORnrARE7eM/usKMECp+7syUwAUKxDCZkGiUdskmOhhBGL\r\nJtbyK3F2UvoJoLsm3pIcvMak9KwMjSTGJB47ABUP1+w+zGcNk0D5Co3IJ6QekiLfWJyQ+kKsWLKt\r\nzOYQQatrnBagM7MI2/T4\r\n"

  attribute_statements {
    type         = "GROUP"
    name         = "groups"
    filter_type  = "REGEX"
    filter_value = ".*"
  }
}

data "okta_app_signon_policy" "test" {
  app_id = okta_app_saml.test.id
}

resource "okta_user" "test" {
  count      = 5
  first_name = "TestAcc"
  last_name  = "Smith"
  login      = "testAcc_${count.index}@example.com"
  email      = "testAcc_${count.index}@example.com"
}

resource "okta_group" "this" {
  count       = 5
  name        = "testAcc_${count.index}"
  description = "testAcc_${count.index}"
}

resource "okta_user_type" "test" {
  name         = "testAcc_replace_with_uuid"
  display_name = "Terraform Acceptance Test User Type Updated"
  description  = "Terraform Acceptance Test User Type Updated"
}

resource "okta_network_zone" "test" {
  name     = "testAcc_replace_with_uuid"
  type     = "IP"
  gateways = ["1.2.3.4/24", "2.3.4.5-2.3.4.15"]
  proxies  = ["2.2.3.4/24", "3.3.4.5-3.3.4.15"]
  status   = "ACTIVE"
}

data "okta_user_type" "default" {
  name = "user"
}

resource "okta_policy_device_assurance_android" "test" {
  name       = "test"
  os_version = "12"
  jailbreak  = false
}

resource "okta_app_signon_policy_rule" "test" {
  name                 = "testAcc_replace_with_uuid_updated"
  policy_id            = data.okta_app_signon_policy.test.id
  access               = "ALLOW"
  custom_expression    = "user.status == \"ACTIVE\""
  device_is_managed    = false
  device_is_registered = true
  factor_mode          = "2FA"
  groups_excluded = [
    okta_group.this[2].id,
    okta_group.this[3].id,
    okta_group.this[4].id
  ]
  groups_included = [
    okta_group.this[0].id,
    okta_group.this[1].id
  ]
  device_assurances_included = [
    okta_policy_device_assurance_android.test.id
  ]
  network_connection = "ZONE"
  network_includes = [
    okta_network_zone.test.id
  ]
  platform_include {
    os_type = "ANDROID"
    type    = "MOBILE"
  }
  platform_include {
    os_type = "IOS"
    type    = "MOBILE"
  }
  platform_include {
    os_type = "MACOS"
    type    = "DESKTOP"
  }
  # FIXME Okta API for /api/v1/policies/{policyId}/rules/{ruleId}
  # is not returning os_expression even when it has been set throwing off the TF state.
  #  platform_include {
  #    os_expression = ".*"
  #    os_type = "OTHER"
  #    type    = "DESKTOP"
  #  }
  #  platform_include {
  #    os_expression = ".*"
  #    os_type = "OTHER"
  #    type    = "MOBILE"
  #  }
  risk_score = "MEDIUM"
  platform_include {
    os_type = "WINDOWS"
    type    = "DESKTOP"
  }
  platform_include {
    os_type = "CHROMEOS"
    type    = "DESKTOP"
  }
  priority                    = 98
  re_authentication_frequency = "PT43800H"
  inactivity_period           = "PT2H"
  type                        = "ASSURANCE"
  user_types_excluded = [
    okta_user_type.test.id
  ]
  user_types_included = [
    data.okta_user_type.default.id
  ]
  users_excluded = [
    okta_user.test[2].id,
    okta_user.test[3].id,
    okta_user.test[4].id
  ]
  users_included = [
    okta_user.test[0].id,
    okta_user.test[1].id
  ]
  constraints = [
    jsonencode({
      "knowledge" : {
        "reauthenticateIn" : "PT2H",
        "types" : ["password"]
      },
      "possession" : {
        "deviceBound" : "REQUIRED"
      }
    }),
    jsonencode({
      "possession" : {
        "deviceBound" : "REQUIRED",
        "hardwareProtection" : "REQUIRED",
        "userPresence" : "OPTIONAL"
      }
    })
  ]
}


If your team has expertise in all of those areas and can comfortably develop configuration changes manually as code, then Terraform might be a great fit.

Salto doesn’t rely on coding directly in a configuration language. Instead, Okta admins can keep developing changes in the dev environment using the Okta Admin Console, then Salto would fetch those changes and translate them to code. There are two options for deploying those changes to higher environments: either using Salto’s UI or with standard automated tools (such as Git and CI/CD pipelines) that can be integrated with Salto.

While Salto relies on a code-based representation of your configuration, it doesn’t require administrators to be proficient in that representation or to be able to modify it as code. If your IAM team has Okta expertise without a deep understanding of Terraform and infrastructure automation, Salto would be a better fit.

❗ What does it look like in terms of core strength and skill set in your team? If it’s mostly Okta and IAM expertise, then Salto would be a better fit. Alternatively, if the team deeply understands Terraform and infrastructure automation, then Terraform would fit well.

Immutability

One of Terraform’s assumptions is that changes are always done using code and never directly in the service itself. This assumption makes perfect sense when managing your infrastructure provider (such as AWS), but things become tricky when you need to manage a rich no/low-code UI-based solution like Okta. It's common for a team to have changes done in the service itself when some team members are Okta experts who are more comfortable working with the Okta UI rather than in code (as mentioned above). Another case is if changes (hotfixes) done directly in production. While changes normally shouldn’t be done directly in production, there are some cases where it makes sense.

With Terraform, a direct service change would create a discrepancy between the Terraform state file and the real state of the service—and would require careful specific handling. These changes may be discovered right before an attempt to deploy a change and can cause significant delays.

With Salto, such changes will be detected automatically. Detected changes in lower environments are funneling into the same release pipeline as changes done through code editing, in a streamlined manner. When changes are detected in production, the user can decide whether they should be reverted or accepted (and back-promoted to lower environments).

Configuration deployment modes

Terraform deployment mode is simple and follows a standard development process: develop the code and deploy it (so it’s always “source driven”).

Salto supports multiple deployment modes:

  1. Tenant-to-tenant compare and deploy: Compare the configurations of two tenants and deploy changes between them
  2. Change-based deployments: Detect changes done to a tenant in a certain time frame and deploy them (or a subset of them) to another instance
  3. Source-driven
  4. Restore: Compare the current version to a historical point in time and selectively deploy historical configuration elements as needed

Supported applications

While this post is focused on Okta, it’s worth mentioning that both solutions support many other applications.

Terraform has thousands of providers and is typically focused on infrastructure solutions such as AWS, GCP, and Azure. Salto supports multiple applications as well, with a focus on IT and business applications (Jira, Salesforce, Zendesk, Okta, Google Workspace, NetSuite, and more).

One thing to consider here is if your Okta implementation needs to be synergetic with other enterprise applications you’re using.

User interface

Terraform is great if you are comfortable working in a CLI, and potentially in an IDE. There are also commercial offerings such as Terraform Cloud, Env0, and Spacelift that add a UI to orchestrate changes already done in code.

Salto can be used from a CLI and also has a powerful web-based UI that enables your team to:

  • Explore and understand your Okta configuration and dependencies in it
  • Understand differences between multiple tenants (a tenant diff tool)

Packaging

Terraform is licensed under the Business Source License and has various commercial SaaS offerings on top that provide a managed service (such as Terraform Cloud, Env0, Spacelift, etc.)

Salto is based on an open-source project (licensed under Apache 2.0 license). Salto’s SaaS offering has two tiers: a free-for-life tier for configuration visibility and a commercial tier that enables deployments, configuration backup, monitoring, and many more features.

To summarize this comparison, choosing between Salto and Terraform for managing your Okta configuration largely depends on your team's technical expertise and the flexibility you need in your change management process. By considering the strengths and limitations of each tool, you can make an informed decision that best suits your operational requirements and strategic goals.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

WRITTEN BY OUR EXPERT

Gil Hoffer

Co-Founder, CTO

Gil is co-founder and CTO at Salto. He started programming at the age of 6 (Basic on Commodore64), and has been around computers ever since. Loves to build stuff—products, systems, teams, and organizations. Ex-VP Engineering at Oracle, VP R&D at Ravello Systems, IDF’s Unit 8200.