Changing Terraform provider.go file - terraform

I'm modifying Terraform provider.go file locally for development testing purposes. I need to add efs endpoint, something that looks like this
"efs": {
Type: schema.TypeString,
Optional: true,
Default: "",
Description: descriptions["efs_endpoint"],
},
I'm trying to put it under endpointsSchema function
My question:
What is required to successfully build Terraform locally with my changes?
Do I need to manually build the plugin and place it under home/user/.terraform.d/plugins (link)? Or make dev for Terraform would be enough?

I solved the problem by modifying the endpoints as in this PR.
Terraform searches for plugins in $GOPATH/bin. My advice is to run terraform from $GOPATH/bin and having the plugin in the same directory. For some reason, Terraform wasn't able to pickup the plugin properly otherwise.

Related

How can I pass secrets in a Terraform resource?

context: I'm adding a new resource foo to Terraform provider.
The interesting detail about foo is that the corresponding POST API request requires to pass 0 or more secret values (best represented as a TypeMap) and then these secrets are pretty much useless (both READ, UPDATE work without it) and I think it doesn't really makes sense to store these secrets in Terraform configuration / state which is why I'd like to set this secrets_map attribute to either null or empty map.
So I started with this definition for this resource:
"secrets_map": {
Type: schema.TypeMap,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Sensitive: true,
Optional: true,
Computed: true,
ForceNew: false,
},
I picked Optional + Computed over Required: true because d.Set("secrets_map", make(map[string]string)) was failing but I'm still running into some issues. Is there an example of such a setup?
My ideal workflow would be:
Import works doesn't require user to set secrets_map at all.
Initially a user sets secrets_map attribute to allow Terraform Provider to read secrets to set them in CREATE request and then terraform apply / plan to ensure everything is in sync and then a user deletes this block from their TF configuration file, runs terraform apply to update secrets_map in TF state and then there're no changes when someone runs terraform plan.
I also figured DiffSurpressFunc doesn't really work for TypeMap which is a bummer: Is it possible to use DiffSuppressFunc for a TypeMap in Terraform SDK v2?
My newest idea is to set secrets_map to null in fooRead().

terraform interpolation with variables returning error [duplicate]

# Using a single workspace:
terraform {
backend "remote" {
hostname = "app.terraform.io"
organization = "company"
workspaces {
name = "my-app-prod"
}
}
}
For Terraform remote backend, would there be a way to use variable to specify the organization / workspace name instead of the hardcoded values there?
The Terraform documentation
didn't seem to mention anything related either.
The backend configuration documentation goes into this in some detail. The main point to note is this:
Only one backend may be specified and the configuration may not contain interpolations. Terraform will validate this.
If you want to make this easily configurable then you can use partial configuration for the static parts (eg the type of backend such as S3) and then provide config at run time interactively, via environment variables or via command line flags.
I personally wrap Terraform actions in a small shell script that runs terraform init with command line flags that uses an appropriate S3 bucket (eg a different one for each project and AWS account) and makes sure the state file location matches the path to the directory I am working on.
I had the same problems and was very disappointed with the need of additional init/wrapper scripts. Some time ago I started to use Terragrunt.
It's worth taking a look at Terragrunt because it closes the gap between Terraform and the lack of using variables at some points, e.g. for the remote backend configuration:
https://terragrunt.gruntwork.io/docs/getting-started/quick-start/#keep-your-backend-configuration-dry

Gatsby extend ESLint rules overwrites original ESLint

I am following the directions in the documentation https://www.gatsbyjs.org/docs/eslint/, and would like to overwite one of the rules, but not affect the others, what I did is create an .eslintrc.js file.
This is the content of the file
module.exports = {
globals: {
__PATH_PREFIX__: true,
},
extends: `react-app`,
"rules": {
'jsx-a11y/no-static-element-interactions': [
'error',
{
handlers: [
'onClick',
'onMouseDown',
'onMouseUp',
'onKeyPress',
'onKeyDown',
'onKeyUp',
],
},
],
}
}
but the rest of the rules are now ignored, like it was not an extension
While the answer above is correct, it is a bit incomplete. The thing is eslint can be integrated both in builds and editors.
When you start using a custom .eslintrc.js you will lose the integration on build and output in the terminal based on those rule. That's because the built-in eslint-loader is disabled when you use a custom file. It actually says so on the documentation page but it is a bit unclear.
To get that back, you will need to integrate it in the webpack build. The easiest way is using the plugin mentioned on the doc page: gatsby-plugin-eslint.
I filed an issue to make custom integrations easier.
From the Gatsby docs you linked to:
When you include a custom .eslintrc file, Gatsby gives you full control over the ESLint configuration. This means that it will override the built-in eslint-loader and you need to enable any and all rules yourself. One way to do this is to use the Community plugin gatsby-eslint-plugin. This also means that the default ESLint config Gatsby ships with will be entirely overwritten. If you would still like to take advantage of those rules, you’ll need to copy them to your local file.
So it looks like as soon as your create a .eslintrc.js file, you need to build your rules up from the bottom again. It overwrites, it doesn't extend.

Use variable in Terraform remote backend

# Using a single workspace:
terraform {
backend "remote" {
hostname = "app.terraform.io"
organization = "company"
workspaces {
name = "my-app-prod"
}
}
}
For Terraform remote backend, would there be a way to use variable to specify the organization / workspace name instead of the hardcoded values there?
The Terraform documentation
didn't seem to mention anything related either.
The backend configuration documentation goes into this in some detail. The main point to note is this:
Only one backend may be specified and the configuration may not contain interpolations. Terraform will validate this.
If you want to make this easily configurable then you can use partial configuration for the static parts (eg the type of backend such as S3) and then provide config at run time interactively, via environment variables or via command line flags.
I personally wrap Terraform actions in a small shell script that runs terraform init with command line flags that uses an appropriate S3 bucket (eg a different one for each project and AWS account) and makes sure the state file location matches the path to the directory I am working on.
I had the same problems and was very disappointed with the need of additional init/wrapper scripts. Some time ago I started to use Terragrunt.
It's worth taking a look at Terragrunt because it closes the gap between Terraform and the lack of using variables at some points, e.g. for the remote backend configuration:
https://terragrunt.gruntwork.io/docs/getting-started/quick-start/#keep-your-backend-configuration-dry

understand the terraform for OCI

I have 3 questions here:
I have created terraform form scripts in Oracle Cloud Infrastructure to build the instance and other resources. But I am not able to get any script for route table configuration and service in network script. So i have made them manual. my current table has only the resource name, rest all configuration is blank. So i need help in getting a properly supported script for OCI to create route table with configuration.
As i did such things manually, i am not able to give terraform apply after doing some changes in the script, as terraform apply will delete all the rules which i created manually. So is it mandatory to give terraform apply every time when i change the script? or can i enter the config manually and simultaneously match that in the terraform script so that everything is intact?
After every terraform changes i could see 2 files is getting enlarge (terraform.tfstate, terraform.tfstate.backup) what are these two files? if that is a backup file, then how will it help me to restore if i mess up in my configuration?
In Terraform, the configuration script is always the source of truth. When you apply a configuration; Terraform will favor the settings of that configuration and override any changes that were manually done outside of Terraform.
To make sure your manual changes are not overwritten, you should make sure the configuration always matches the manual changes. One way to import manual resources into your configuration is using "terraform import" (see https://www.terraform.io/docs/import/index.html).
The terraform.tfstate and terraform.tfstate.backup files are used by Terraform to keep track of the latest state of the resources that Terraform has created. These files are used to help Terraform determine whether you configuration script has drifted from the state; so it knows how to apply your configuration script. To my knowledge, these state files are not intended to be backup files if you mess up your configuration. (see https://www.terraform.io/docs/state/index.html)
Hope this helps.
Here is an example for a route table resource in Terraform config file:
resource "oci_core_route_table" "webserver-rt" {
compartment_id = "${var.compartment_ocid}"
vcn_id = "${oci_core_virtual_network.oci-vcn.id}"
display_name = "webserver-rt"
route_rules = [{
destination = "0.0.0.0/0"
network_entity_id = "${oci_core_internet_gateway.internet-gateway.id}"
}]
}
You may find more details here: https://github.com/terraform-providers/terraform-provider-oci/blob/master/docs/examples/networking/route_table/route_table.tf

Resources