Allocate AWS SSO Permission Set to Groups in Accounts - terraform

Working to fully code the aws sso set up
So far coded via Terraform I have all permission-sets and using scim to pull in groups.
Allocation of the permission sets to groups in accounts (I have over 100 accounts) is done by hand. I want to allocate permission sets to groups in selected accounts via IaC (Terraform) but I cant for the life of me find working code.
Ive tried using
aws_sso_permission_set_group_assignment,
aws_sso_permission_set_group_attachment,
aws_sso_group_permission_set_assignment,
aws_sso_group_permission_set_attachment,
aws_sso_permission_set_attachment,
aws_sso_permission_set_assignment,
These i found in some old docs but they dont work :( giving The provider hashicorp/aws does not support resource type
Does anyone have any advice they can offer of how to remedy this or how they managed to surmount this issue
Here is example of code tried
resource "aws_sso_group_permission_set_attachment" "example" {
group_id = "93sd433ee-cd43e4b-cfww-434e-re33-707a0987eb"
permission_set_id = "arn:aws:sso:::permissionSet/ssoins-63456a11we432d8/ps-1231ded3d42fcrr2"
account_id = "8765322052550"
}
resource "aws_sso_group_permission_set_attachment" "example" {
permission_set_arn = "arn:aws:sso:::permissionSet/ssoins-63456a11we432d8/ps-1231ded3d42fcrr2"
group_name = "93sd433ee-cd43e4b-cfww-434e-re33-707a0987eb"
account_id = "8765322052550"
}

ssoadmin_account_assignment resource is something which you might be looking for, please go through all the available attributes in the resource to match your needs.
resource "aws_ssoadmin_account_assignment" "example" {
instance_arn = tolist(data.aws_ssoadmin_instances.example.arns)[0]
permission_set_arn = "arn_of_the_permission_set" # replace this with actually permission set arn
principal_id = "group_id" # replace this with groupID
principal_type = "GROUP"
target_id = "012347678910" # replace with account ID
target_type = "AWS_ACCOUNT"
}

Related

Automating Permissions for Databricks SQL Tables or Views

Trying to automate the setup of Databricks SQL.
I have done it from the UI and it works, so this is a natural next step.
The one thing I am unsure about is how to automate granting of the access to SQL tables and/or views using REST. I am trying to avoid a Notebooks job.
I have seen this microsoft documentation and downloaded the specification but when I opened it with Postman, I see permissions/objectType/Object id, but the only sample I have seen there is for "queries". It just seems to be applicable for Queries and Dashboards. Can't this be done for Tables and views? There is no further documentation that I could see.
So, basically how to do something like
grant select on tablename to group using REST api without using a Notebook job. I am interested to see if I can just call a REST endpoint from our release pipeline (Azure DevOps)
As of right now, there is no REST API for setting Table ACLs. But it's available as part of the Unity Catalog that is right now in the public preview.
If you can't use Unity Catalog yet, then you still have a possibility to automate assignment of Table ACLs by using databricks_sql_permissions resource of Databricks Terraform Provider - it sets permissions by executing SQL commands on a cluster, but this is hidden from administrator.
This is an extension to Alex Ott `s answer giving some details on what I tried to make the databricks_sql_permissions Resource work for Databricks SQL as was the OP's original question. All this assumes that one does not want/can use Unity Catalog which follows a different permission model and has a different Terraform resource, namely databricks_grants Resource.
Alex`s answer refers to table ACLs which had me surprised as the OP (and myself) were looking for Databricks SQL object security and not table ACLs in the classic workspace. But from what I understand so far, it seems the two are closely interlinked and the Terraform provider addresses table ACLs in the classic workspace (i.e. non-SQL) which are mirrored to SQL objects in the SQL workspace. It follows that if you like to steer SQL permissions in Databricks SQL via Terraform, you need to enable table ACLs in classic workspace (in admin console). If you (for whatever reason) cannot enable table ACLs, it seems to me the only other option is via sql scripts in the SQL workspace with the disadvantage of having to explicitly write out grants and revokes. Potentially an alternative is to throw away all permissions before one only runs grant statements but this has other negative implications.
So here is my approach:
Enable table ACL in classic workspace (this has no implications in classic workspace if you don`t use table ACL-enabled clusters afaik)
Use azurerm_databricks_workspace resource to register Databricks Azure infrastructure
Use databricks_sql_permissions Resource to manage table ACLs and thus SQL object security
Below is a minimal example that worked for me and may inspire others. It certainly does not follow Terraform config guidance but is merely used for minimal illustration.
NOTE: Due to a Terraform issue I had to ignore changes from attribute public_network_access_enabled, see GitHub issues: "azurerm_databricks_workspace" forces replacement on public_network_access_enabled while it never existed #15222
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.0.0"
}
databricks = {
source = "databricks/databricks"
version = "=1.4.0"
}
}
backend "azurerm" {
resource_group_name = "tfstate"
storage_account_name = "tfsa"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
provider "azurerm" {
features {}
}
provider "databricks" {
azure_workspace_resource_id = "/subscriptions/mysubscriptionid/resourceGroups/myresourcegroup/providers/Microsoft.Databricks/workspaces/mydatabricksworkspace"
}
resource "azurerm_databricks_workspace" "adbtf" {
customer_managed_key_enabled = false
infrastructure_encryption_enabled = false
load_balancer_backend_address_pool_id = null
location = "westeurope"
managed_resource_group_name = "databricks-rg-myresourcegroup-abcdefg12345"
managed_services_cmk_key_vault_key_id = null
name = "mydatabricksworkspace"
network_security_group_rules_required = null
public_network_access_enabled = null
resource_group_name = "myresourcegroup"
sku = "premium"
custom_parameters {
machine_learning_workspace_id = null
nat_gateway_name = "nat-gateway"
no_public_ip = false
private_subnet_name = null
private_subnet_network_security_group_association_id = null
public_ip_name = "nat-gw-public-ip"
public_subnet_name = null
public_subnet_network_security_group_association_id = null
storage_account_name = "dbstorageabcde1234"
storage_account_sku_name = "Standard_GRS"
virtual_network_id = null
vnet_address_prefix = "10.139"
}
tags = {
creator = "me"
}
lifecycle {
ignore_changes = [
public_network_access_enabled
]
}
}
data "databricks_current_user" "me" {}
resource "databricks_sql_permissions" "database_test" {
database = "test"
privilege_assignments {
principal = "myuser#mydomain.com"
privileges = ["USAGE"]
}
}
resource "databricks_sql_permissions" "table_test_student" {
database = "test"
table = "student"
privilege_assignments {
principal = "myuser#mydomain.com"
privileges = ["SELECT", "MODIFY"]
}
}
output "adb_id" {
value = azurerm_databricks_workspace.adbtf.id
}
NOTE: Serge Smertin (Terraform Databricks maintainer) mentioned in GitHub issues: [DOC] databricks_sql_permissions Resource to be deprecated ? #1215 that the databricks_sql_permissions resource is deprecated but I could not find any indication about that in the docs, only a recommendation to use another resource when leveraging Unity Catalog which I'm not doing.

Vault - Assign multiple aliases for one identity group

I've been trying to assign multiple group aliases, meaning, multiple AD groups in our company, into one identity group. So far we've had an identity group for each alias, and we realized that doesn't make sense, as they all carry the same policies.
We are using Terraform in order to maintain and provision our infrastructure.
This is my expected form:
resource "vault_identity_group" "saas-mfi" {
metadata = {
productname = "mfi"
}
name = "saas-mfi"
policies = [
"eaas-key",
"secret-store-mfi"
]
type = "external"
}
resource "vault_identity_group_alias" "alias_1" {
canonical_id = vault_identity_group.saas-mfi.id
mount_accessor = var.org_local_mount_accessor
name = "alias_1"
}
resource "vault_identity_group_alias" "alias_2" {
canonical_id = vault_identity_group.saas-mfi.id
mount_accessor = var.org_local_mount_accessor
name = "alias_2"
}
resource "vault_identity_group_alias" "alias_3" {
canonical_id = vault_identity_group.saas-mfi.id
mount_accessor = var.org_local_mount_accessor
name = "alias_3"
}
When I try to apply this configuration, I get the following error:
Error: Provider produced inconsistent result after apply
Of course, the issue does not stand with the provider. But it seems like one identity group can't have more than one alias to itself. Which is weird, as in the UI, there is a tab for identity groups called "Aliases", in plural.
If anybody has any information regarding this matter, I would really appreciate that.
I was trying to do the same thing but just came across the following paragraph in the documentation for identity:
External group serves as a mapping to a group that is outside of the identity store. External groups can have one (and only one) alias. This alias should map to a notion of group that is outside of the identity store.
From the section on External vs Internal Groups.

COS access policies interface vs terraform

In interface I can go to COS Bucket Access Policies and easily assign policy that then looks more or less like:
Cloud Object Storage service
serviceInstance string equals foo-bar, resource string equals foo-bar-pcaps, resourceType string equals bucket
I'm struggling to find a way to do the same via terraform because whenever I try with the proper TF code like:
resource "ibm_iam_service_policy" "policy_pcaps" {
iam_service_id = ibm_iam_service_id.serviceID_pcaps.id
roles = ["Writer"]
resources {
service = "cloud-object-storage"
resource = ibm_cos_bucket.pcaps.id
}
}
I'm ending up with
Cloud Object Storage service
resource string equals crn:v1:bluemix:public:cloud-object-storage:global:a/27beaaea79a<redacted>34dd871b:8b124bc6-147c-47ba-bd47-<redacted>:bucket:foo-bar-pcaps:meta:rl:us-east
The problem is that the Writer policy that is required here does not work properly with that policy details.
How to achieve something similar to the first policy with Terraform?
Thanks
You can achieve this similar to this example Service Policy by using attributes.
I created a policy through the UI for Cloud Object Storage and specified the policy to contain a bucket name. Then I used:
ibmcloud iam access-group-policy GROUP_NAME POLICY_ID --output JSON
to get a better understanding of the policy.
With that I created this sample terraform snippet and tested it. It is creating the IAM access group + policy:
resource "ibm_iam_access_group" "accgrp_cos" {
name = "test_cos"
}
resource "ibm_iam_access_group_policy" "policy" {
access_group_id = ibm_iam_access_group.accgrp_cos.id
roles = ["Writer"]
resources {
service = "cloud-object-storage"
attributes = {
resourceType = "bucket"
resource = "tf-test-cos"
}
}
}

Terraform - assigning one group to each created IAM user

How can I assign during creation of IAM users with below code to one group existing alredy in AWS?
resource "aws_iam_user" "developer-accounts" {
path = "/"
for_each = toset(var.names)
name = each.value
force_destroy = true
}
resource "aws_iam_user_group_membership" "developers-membership" {
user = values(aws_iam_user.developer-accounts)[*].name
groups = [data.aws_iam_group.developers.group_name]
}
With above code I’m getting
inappropriate value for attribute “user”: string required.
Users variable used:
variable "names" {
description = "account names"
type = list(string)
default = ["user-1", "user-2", "user-3",...etc]
}
2nd part of question. With below I want to create passwords for each users:
resource "aws_iam_user_login_profile" "devs_login" {
for_each = toset(var.names)
user = each.value
pgp_key = "keybase:macdrorepo"
password_reset_required = true
}
Output:
output "all_passwordas" {
value = values(aws_iam_user_login_profile.devs_login)[*].encrypted_password
}
How can I decode the passwords? Below is not working as I'm sure missing some kind of loop...
terraform output all_passwordas | base64 --decode | keybase pgp
decrypt
For your first question, the following should do the trick:
You need to iterate over all users again and attach groups to each of them:
resource "aws_iam_user_group_membership" "developers-membership" {
for_each = toset(var.names)
user = aws_iam_user.developer-accounts[each.key].name
groups = [data.aws_iam_group.developers.group_name]
}
To answer your second question: You are trying to decrypt all user passwords at once, which will not work as expected. Instead, you need to decrypt each users password one by one. You could use tools like jq to loop over terraform output -json output.
Just a small note. It's better to open two questions instead of adding multiple (unrelated) questions into one. I hope this answer helps.

Terrafrom v11.13 Attach Multiple Data Templates To Single Resource

I'm running Terraform v11.13 with the AWS provider. Is it possible to attach multiple data template files to a single resource?
An example of this is where you have a single aws_iam_policy resouce, but for it to create multiple IAM polices from different data template files.
It works when it is just a single data template file with a count index. It also works when the file is static, as in not a template file.
Here is the code example
variable "policy_list"{
type = "list"
default = ["s3,"emr","lambda"]
}
resource "aws_iam_policy" "many_policies" {
count = "${length(var.policy_list)}"
name = "Policy_${var.policy_list[count.index]}_${var.environment}"
policy = "${file("${path.module}/files/policies/${var.environment}/${var.policy_list[count.index]}.json")}"
}
resource "aws_iam_role_policy_attachment" "many_policies_attachment" {
count = "${length(var.policy_list)}"
role = "${aws_iam_role.iam_roles.*.name[index(var.role_list, "MyRole"))]}"
policy_arn = "${aws_iam_policy.many_policies.*.arn[count.index]}"
}
But what fails is
resource "aws_iam_policy" "many_policies" {
count = "${length(var.policy_list)}"
name = "Policy_${var.policy_list[count.index]}_${var.environment}"
policy = "${data.template_file.${var.policy_list[count.index]}_policy_file.*.rendered[count.index]}"
}
With an error message similar to
parse error expected "}" but found invalid sequence "$"
Any ideas on how this can be achieved?
Based on the errors messages and the suggestion by Matt Schuchard, it's fair to conclude that the data.template_file option does not support interpolation in v11.13

Resources