I am able to configure diagnostic settings for azure data bricks in the portal,I need a ARM template to automate the creation of diagnostic settings for azure data bricks.
let me know if any additional information required from my side.
Thanks in advance
Diagnostic settings for Azure Databricks Workspace are configured separately from its creation - you can use standard ARM templates for Azure Monitor that you can find in the documentation. You just need to select what category of diagnostic you want to enable, and modify ARM template correspondingly (the full list of categories could be found in the UI, here is the partial list: "dbfs", "clusters", "accounts", "jobs", "notebook", "ssh", "workspace", "secrets", "sqlPermissions", "instancePools").
If you're able to use Terraform, you can enable diagnostic settings via it as well, with something like this:
data "azurerm_databricks_workspace" "example" {
name = var.workspace_name
resource_group_name = var.resource_group
}
data "azurerm_eventhub_namespace_authorization_rule" "test" {
name = "test"
resource_group_name = var.resource_group
namespace_name = var.evhub_ns_name
}
resource "azurerm_monitor_diagnostic_setting" "test" {
name = "test"
target_resource_id = data.azurerm_databricks_workspace.example.id
eventhub_authorization_rule_id = data.azurerm_eventhub_namespace_authorization_rule.test.id
eventhub_name = var.evhub_name
dynamic "log" {
for_each = var.enabled_log_types
content {
category = log.value
enabled = true
}
}
}
variable resource_group {
type = string
description = "Resource group to deploy"
}
variable region {
type = string
description = "Region to deploy"
}
variable evhub_ns_name {
type = string
description = "Name of eventhub namespace"
}
variable evhub_name {
type = string
description = "Name of EventHubs topic"
}
variable workspace_name {
type = string
description = "The name of DB Workspace"
}
variable enabled_log_types {
type = list(string)
description = "List of the log types to enable"
default = ["dbfs", "clusters", "accounts", "jobs", "notebook", "ssh",
"workspace", "secrets", "sqlPermissions", "instancePools"]
}
Related
We created okta users, and okta groups using terraform
This is variables.tf
used variable list object for users and groups
variable "users" {
type = list(object
({
first_name = string
last_name = string
email = string
organization = string
role = string
okta_admin = bool
}))
}
variable "groups" {
type = list(object
({
name = string
description = string
}))
}
This is terraform.tfvars
groups = [
{ name = "dev", description = "This group for Devlopers" },
{ name = "qa", description = "This group for QA" },
{ name = "per", description = "This group for Per" }
]
users = [
{ first_name = "a", last_name = "a", email = "a#gmail.com", role = "Engineer", organization = "organization", okta_admin = true },
{ first_name = "b", last_name = "b", email = "b#gmail.com", role = "Lead", organization = "organization", okta_admin = true },
{ first_name = "c", last_name = "c", email = "c#gmail.com", role = "Devloper", organization = "organization", okta_admin = false },
]
this is main.tf
to get the values used for_each
resource "okta_group" "groups" {
for_each = { for group in var.groups : join("-", [group.name, group.description]) => group }
name = each.value.name
description = each.value.description
}
resource "okta_user" "okta_user_add" {
for_each = { for user in var.users : join("-", [user.first_name, user.last_name]) => user }
title = each.value.role
email = each.value.email
first_name = each.value.first_name
last_name = each.value.last_name
login = each.value.email
organization = each.value.organization
}
when we are trying to get id we tried multiple things but it didn't work for us.
unable to get the group id and user id's
resource "okta_group_memberships" "okta_member_group" {
for_each = okta_group.groups
group_id = each.value.id # I want only select one group
users = users = values(okta_user.okta_user_add)[*].id
}
my question is
okta_group_memberships.okta_member_group
we have multiple groups but we need only one group to add in okta_group_memberships.
and we also to add specific user. I mention in tfvars file. there users object we have okta_admin = true. we need only those users we need in the okta_member_group
For retrieving all the group id, you could iterate over the okta_user resources:
resource "okta_group_memberships" "okta_member_group" {
group_id = each.value.id
# Add all users to each group
users = values(okta_user.okta_user_add)[*].id
}
The problem with your question is that you don't specify anywhere which user belongs to which group, so I've used a splat expression to get all the ids of all the users.
You should create a separate input variable in order to map each user to certain group.
Edit:
locals {
# get DEV group
dev_group = [for group in var.groups: group if group.name == "dev"][0]
# filter okta admins
okta_admins = [for user in var.users: join("-", [user.first_name, user.last_name]) if user.okta_admin]
}
resource "okta_group_memberships" "okta_member_group" {
# select only the DEV group
group_id = okta_group.groups[join("-", [local.dev_group.name, local.dev_group.description])].id
# get IDs of okta_admins only
users = [for okta_admin in local.okta_admins: okta_user.okta_user_add[okta_admin].id]
}
I am using Google autocomplete API in a react app. By default, the user can enter a street address or the name of a business in the autocomplete search field and google will autocomplete it. How can I restrict the autocomplete field to only autocomplete business names?
You can set the type as establishment.
Here is an example code:
let autocomplete;
function initMap() {
autocomplete = new google.maps.places.Autocomplete(
document.getElementById("autocomplete"),
{
types: ["establishment"],
componentRestrictions: { country: ["US"] },
fields: ["place_id", "geometry", "name", "formatted_address"],
}
);
autocomplete.addListener("place_changed", onPlaceChanged);
}
function onPlaceChanged() {
var place = autocomplete.getPlace();
if (!place.geometry) {
document.getElementById("autocomplete").placeholder = "Enter a place";
} else {
document.getElementById("business-name").innerHTML = place.name;
document.getElementById("full-address").innerHTML =
place.formatted_address;
}
}
For more info you can check the doc here
I am trying to use terraform to get an aws_ami data resource as follows:
data "aws_ami" "fedora_atomic" {
most_recent = true
filter {
name = "name"
values = [
"ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"] <==== What to specify here?
}
filter {
name = "virtualization-type"
values = [
"hvm"]
}
owners = [
"099720109477"] <=== What's the owner id?
# Canonical
}
But I want to replace the above with the following image desription, which I found on the AWS console:
Fedora-Atomic-25-20170727.0.x86_64-us-east-1-HVM-standard-0 - ami-00035c7b
Question
How do I find the right values for the fields above i.e. what is the correct code for the above for a Fedora Atomic image?
I am struggling to find this information.
Many Thanks
Fedora Atomic has been EOL since 2019 and you won't find new AMIs but to answer your question, the owner is the Account ID and you can find it from the AWS Console
The name can be part of what is available in the description, ie Fedora-Atomic-25-
Combining them all
data "aws_ami" "fedora_atomic" {
most_recent = true
filter {
name = "name"
values = ["Fedora-Atomic-25-*"]
}
filter {
name = "virtualization-type"
values = [ "hvm"]
}
owners = ["125523088429"]
}
output "ami" {
value = data.aws_ami.fedora_atomic.id
}
I am spinning up multiple Amazon EC2 instances and need to attach a Security Group. I am able to achieve it for one EC2 instance but looking for solution for multiple EC2s. I am using TerraForm 0.12. Please let me know how can I use data resource :- data "aws_instances" (s).
Here is the code for single EC2 which i am trying to convert for multiple EC2s:
resource "aws_instance" "ec2_instance" {
count = "${var.ec2_instance_count}"
ami = "${data.aws_ami.app_qrm_ami.id}"
...
}
data "aws_instances" "ec2_instances" {
count = "${var.ec2_instance_count}"
filter {
name = "instance-id"
values = ["${aws_instance.ec2_instance.*.id[count.index]}"]
}
}
resource "aws_network_interface_sg_attachment" "sg_attachment" {
security_group_id = "${data.aws_security_group.security_group.id}"
network_interface_id = "${data.aws_instance.ec2_instance[count.index].network_interface_id}" //facing issues here.
}
I want to achieve this using data "aws_instances" #notice the (s). Thanks in advance.
For removing the Hard coding of ec2 AMI, you can use the following data provider:-
data "aws_ami" "amazon_linux" {
count = "${var.ec2_instance_count}"
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = [
"amzn-ami-hvm-*-x86_64-gp2",
]
}
filter {
name = "owner-alias"
values = [
"amazon",
]
}
}
For rendering the ami id:-
resource "aws_instance" "ec2_instance" {
count = "${var.ec2_instance_count}"
ami = "${data.aws_ami.amazon_linux[count.index].id}"
network_interface =
For getting network_interface_id:-
resource "aws_network_interface" "ec2_nic" {
count = "${var.ec2_instance_count}"
subnet_id = "${aws_subnet.public_a.id}"
private_ips = ["10.0.0.50"]
security_groups = ["${aws_security_group.web.id}"]
attachment {
instance = "${aws_instance.ec2_instance[count.index].id}"
}
}
resource "aws_network_interface_sg_attachment" "sg_attachment" {
security_group_id = "${data.aws_security_group.security_group.id}"
network_interface_id = "${aws_network_interface.ec2_ami[count.index].id}"
}
Thanks Karan, your answer solved the issue for me. Later the infra got fairly complex and I found a different and a smarter way to solve it. I would like to share with other people which might help TF community in future.
multiple internal SG {internal 0-7}and one external to all for creating different groups of swarm which allowed to communicate internal and selectively externally. Majorly used in Microsoft HPC grid.
resource "aws_instance" "ec2_instance" {
count = tonumber(var.mycount)
vpc_security_group_ids = [data.aws_security_group.external_security_group.id, element(data.aws_security_group.internal_security_group.*.id, count.index)]
...
}
resource "aws_security_group" "internal_security_group" {
count = tonumber(var.mycount)
name = "${var.internalSGname}${count.index}"
}
resource "aws_security_group" "external_security_group" {
name = ${var.external_sg_name}"
}
I am trying to implement nested for loops using Terraform 0.12's new features in order to loop through AWS IAM users, each of which can have one or more policies attached. The variable used to represent this list is of type map(list(string)) and looks something like this:
{
"user 1" = [ "policy1", "policy2" ],
"user 2" = [ "policy1" ]
}
Getting the list of users to create is easy enough via keys(), but since there is currently no mechanism for nesting looped resource creation in Terraform, the policy attachments have to happen as a singular loop independent of each user. So, I am attempting to construct a list of user:policy associations from the map input that would look something like this based on the example above:
[
[ "user1", "policy1" ],
[ "user1", "policy2" ],
[ "user2", "policy1" ]
]
I am attempting construct that list and store it in a local variable like so, where var.iam-user-policy-map is the input map:
locals {
...
association-list = [
for user in keys(var.iam-user-policy-map):
[
for policy in var.iam-user-policy-map[user]:
[user, policy]
]
]
...
}
However, I am getting errors when attempting to access the values in that nested list. I am trying to access the user portion of the association with the reference local.association-list[count.index][0] and the policy with local.association-list[count.index][1], but on running terraform plan it errors out:
Error: Incorrect attribute value type
on main.tf line 27, in resource "aws_iam_user_policy_attachment" "test-attach":
27: user = local.association-list[count.index][0]
Inappropriate value for attribute "user": string required.
Error: Incorrect attribute value type
on main.tf line 27, in resource "aws_iam_user_policy_attachment" "test-attach":
27: user = local.association-list[count.index][0]
Inappropriate value for attribute "user": string required.
Error: Invalid index
on main.tf line 28, in resource "aws_iam_user_policy_attachment" "test-attach":
28: policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index][1]}"
|----------------
| count.index is 0
| local.association-list is tuple with 2 elements
The given key does not identify an element in this collection value.
Error: Invalid template interpolation value
on main.tf line 28, in resource "aws_iam_user_policy_attachment" "test-attach":
28: policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index][1]}"
|----------------
| count.index is 1
| local.association-list is tuple with 2 elements
Cannot include the given value in a string template: string required.
What am I doing wrong?
The for expression in your local value association-list is producing a list of list of lists of strings, but your references to it are treating it as a list of lists of strings.
To get the flattened representation you wanted, you can use the flatten function, but because it would otherwise group everything into a single flat list I'd recommend making the innermost value an object instead. (That will also make the references to it clearer.)
locals {
association-list = flatten([
for user in keys(var.iam-user-policy-map) : [
for policy in var.iam-user-policy-map[user] : {
user = user
policy = policy
}
]
])
}
The result of this expression will have the following shape:
[
{ user = "user1", policy = "policy1" },
{ user = "user1", policy = "policy2" },
{ user = "user2", policy = "policy2" },
]
Your references to it can then be in the following form:
user = local.association-list[count.index].user
policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index].policy}"
If you need a map for 'for_each', 'merge' is convenient.
variable "iam-user-policy-map" {
default = {
"user 1" = ["policy1", "policy2"],
"user 2" = ["policy1"]
}
}
locals {
association-map = merge([
for user, policies in var.iam-user-policy-map : {
for policy in policies :
"${user}-${policy}" => {
"user" = user
"policy" = policy
}
}
]...)
}
output "association-map" {
value = local.association-map
}
Outputs:
association-map = {
"user 1-policy1" = {
"policy" = "policy1"
"user" = "user 1"
}
"user 1-policy2" = {
"policy" = "policy2"
"user" = "user 1"
}
"user 2-policy1" = {
"policy" = "policy1"
"user" = "user 2"
}
}
Example for_each usage:
resource "null_resource" "echo" {
for_each = local.association-map
provisioner "local-exec" {
command = "echo 'policy - ${each.value.policy}, user - ${each.value.user}'"
}
}
https://github.com/hashicorp/terraform/issues/22263#issuecomment-969549347
I am not sure where I got this answer from, but this one worked for me.
locals {
schemas = [
"PRIVATE",
"PUBLIC",
"MY_SCHEMA",
]
privileges = [
"CREATE TABLE",
"CREATE VIEW",
"USAGE",
]
# Nested loop over both lists, and flatten the result.
schema_privileges = distinct(flatten([
for schema in local.schemas : [
for privilege in local.privileges : {
privilege = privilege
schema = schema
}
]
]))
}
resource "snowflake_schema_grant" "write_permissions" {
# We need a map to use for_each, so we convert our list into a map by adding a unique key:
for_each = { for entry in local.schema_privileges: "${entry.schema}.${entry.privilege}" => entry }
database_name = "MY_DATABASE"
privilege = each.value.privilege
roles = "DAVE"
schema_name = each.value.schema
}