Security is one of the most important pillars for building robust and reliable infrastructure. Preventing unauthorized access, data breaches, and other security threats is crucial for ensuring integrity and user safety. By leveraging products such as Okta, you can fortify your organization’s security and minimize these problems.
In this post, we will explore what Okta is and how to leverage it using Terraform.
What we will cover:
Okta is an identity access management (IAM) service that provides secure, centralized authentication for your organization’s users. With Okta, you can easily manage user authentication to applications inside your organization using single sign-on (SSO), multi-factor authentication (MFA), and lifecycle management functionalities. Okta helps organizations streamline their access management, enhances overall security, and improves the user experience.
The Okta Terraform provider lets you manage (create/edit/delete) resources in your Okta account. It is very useful, especially in large organizations, where personnel, privileges, and accesses change frequently.
With the Okta Terraform provider, you can automate almost everything that you would do manually as a security administrator:
- Creating users and groups
- Creating policies and roles
- Creating SAML/OIDC identity providers
- Assigning users to different applications
The Terraform documentation for the Okta provider outlines how you can configure the provider, what resources you can create, and what datasources you can leverage.
provider "okta" {
org_name = var.org_name
base_url = var.base_url
api_token = var.api_token
}
To authenticate to Okta, in my provider block I will use an org_name, base_url, and api_token.
variable "org_name" {
description = "The name of the Okta organization"
type = string
}
variable "base_url" {
description = "The base URL of the Okta organization (e.g., okta.com)"
type = string
default = "okta.com"
}
variable "api_token" {
description = "The API token used to authenticate with the Okta API"
type = string
sensitive = true
}
These values can be provided either in the default block of your variables, in a tfvars file, in environment variables, or even by using the “-var” or “-var-file” options.
E.g. terraform.tfvars file
org_name = "dev-123456"
api_token = "your-okta-api-token"
In my example, I will create a configuration that creates the number of users and groups I want and also takes care of their memberships:
resource "okta_user" "users" {
for_each = var.users
first_name = each.value.first_name
last_name = each.value.last_name
email = each.value.email
login = each.value.login
}
resource "okta_group" "groups" {
for_each = var.groups
name = each.value.name
description = each.value.description
}
resource "okta_group_membership" "memberships" {
for_each = var.memberships
group_id = okta_group.groups[each.value.group_name].id
user_id = okta_user.users[each.value.user_name].id
}
As you can see, all resources are created with for each, to enable you to create the number of instances of a resource you want.
variable "users" {
description = "A map of users to be created in Okta"
type = map(object({
first_name = string
last_name = string
email = string
login = string
}))
}
variable "groups" {
description = "A map of groups to be created in Okta"
type = map(object({
name = string
description = string
}))
}
variable "memberships" {
description = "A map of group memberships, associating users with groups"
type = map(object({
group_name = string
user_name = string
}))
}
All the variables are defined as object maps, and none of their parameters are optional, meaning that you will have to provide values for all of them.
In this example, I will create two users, two groups, and two memberships based on a tfvars file:
users = {
user1 = {
first_name = "user"
last_name = "one"
email = "user.one@example.com"
login = "user.one@example.com"
},
user2 = {
first_name = "user"
last_name = "two"
email = "user.two@example.com"
login = "user.two@example.com"
}
}
groups = {
group1 = {
name = "group1"
description = "An example group in Okta"
},
group2 = {
name = "group2"
description = "Another example group in Okta"
}
}
memberships = {
membership1 = {
group_name = "group1"
user_name = "user1"
},
membership2 = {
group_name = "group2"
user_name = "user2"
}
}
This is the output of a terraform apply
:
okta_user.users["user1"]: Creating...
okta_user.users["user2"]: Creating...
okta_group.groups["group1"]: Creating...
okta_group.groups["group2"]: Creating...
okta_user.users["user1"]: Creation complete after 2s [id=...]
okta_group.groups["group2"]: Creation complete after 1s [id=...]
okta_user.users["user2"]: Creation complete after 2s [id=...]
okta_group.groups["group1"]: Creation complete after 1s [id=...]
okta_group_membership.memberships["membership1"]: Creating...
okta_group_membership.memberships["membership1"]: Creation complete after 1s [id=...]
okta_group_membership.memberships["membership2"]: Creating...
okta_group_membership.memberships["membership2"]: Creation complete after 1s [id=...]
Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
There are several benefits of using Terraform to create your Okta resources:
- Consistency – Ensure environments are repeatable and human errors are minimized.
- Version control – Storing your configurations in a VCS lets you track changes and revert to previous versions.
- Scalability – Terraform scales with your needs, so as your organization grows, it will help you provision more resources.
- Collaboration – Changes proposed through pull requests are deployed only after they are reviewed.
If you have a big organization with frequent personnel changes every month, leveraging Terraform for Okta access will make things much easier for the security team responsible for adding/removing these users.
All the benefits of using Terraform apply to the Okta provider. You can read more about it in this article.
You can use Okta as an SSO provider for Spacelift and configure it via OIDC or SAML2.0.
For both of these integrations, go to your Spacelift account first in Organization settings and select single sign-on.
To use SAML, you will need the Single sign-on URL and the Entity ID, and for OIDC you will need the Authorized redirect URL.
Next, go to Okta, create a new application, and select whether you want to configure it via SAML2.0 or OIDC. An example for OIDC is available here.
After you finish creating the application, go back to your Spacelift account and click on the setup button for the method you want to configure.
Apart from integrating Spacelift with Okta for SSO, you can easily leverage any configurations you are building with Terraform from Spacelift to leverage an entire orchestration workflow.
The following Spacelift features can streamline your Okta management:
- Contexts – You can create a context that contains the environment variables required for Okta connection and use the autoattach:label feature to ensure that all stacks with the label will automatically attach it. This means you won’t need to worry about adding these details for each stack you create, which will also force you to add the same label on your Okta stacks, making them easier to manage
- Policies – Plan policies restrict entire Okta resources from being created or just some parameters of these resources. Approval policies ensure a minimum number of approvals are met before making a change to the code. Push policies control what happens when a pull request is open or a merge happens. Notification policies control where to send notifications. These policies can also be created with the autoattach:label feature to ensure that all your stacks will have the necessary policies attached
- Stack dependencies – To keep your state files small but retain a single end-to-end workflow, you can split your stacks into multiple smaller ones and create dependencies that also share outputs between them. This will make you respect Terraform’s best practices and ensure errors are easier to find and solve.
- Blueprints – You can leverage Blueprints to build self-service infrastructure templates for Okta, making it easier for security engineers to create new Okta resources without having to build the code themselves.
In this post, we walked you through what Okta is and how to use its Terraform provider to provision Okta resources. We also showed you the benefits of managing Okta resources with it and how Spacelift integrates with Okta.
If you want to manage Okta with Terraform, Spacelift will take your workflow to the next level while ensuring that governance is met. Create a free account today with Spacelift, or book a demo with one of our engineers to learn more.
Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.
Manage Terraform Better with Spacelift
Spacelift helps manage Terraform state, build more complex workflows, supports policy as code, programmatic configuration, context sharing, drift detection, resource visualization and many more.