Giter VIP home page Giter VIP logo

hashicorp / terraform-provider-null Goto Github PK

View Code? Open in Web Editor NEW
169.0 17.0 68.0 11.19 MB

Utility provider that provides constructs that intentionally do nothing, useful in various situations to help orchestrate tricky behavior or work around limitations.

Home Page: https://registry.terraform.io/providers/hashicorp/null/latest

License: Mozilla Public License 2.0

Makefile 1.06% Go 96.76% HCL 2.18%
terraform terraform-provider null

terraform-provider-null's Introduction

Terraform Provider: Null

The Null provider is a rather-unusual provider that has constructs that intentionally do nothing. This may sound strange, and indeed these constructs do not need to be used in most cases, but they can be useful in various situations to help orchestrate tricky behavior or work around limitations.

Requirements

Documentation, questions and discussions

Official documentation on how to use this provider can be found on the Terraform Registry. In case of specific questions or discussions, please use the HashiCorp Terraform Providers Discuss forums, in accordance with HashiCorp Community Guidelines.

We also provide:

  • Support page for help when using the provider
  • Contributing guidelines in case you want to help this project

Compatibility

Compatibility table between this provider, the Terraform Plugin Protocol version it implements, and Terraform:

Null Provider Terraform Plugin Protocol Terraform
>= 3.0.x 5 >= 0.12
>= 2.1.x 4 and 5 >= 0.12
>= 2.x.x 4 <= 0.12
>= 1.x.x 4 <= 0.12
>= 0.1.x 4 <= 0.12

Details can be found querying the Registry API that return all the details about which version are currently available for a particular provider. Here are the details for Time (JSON response).

Development

Building

  1. git clone this repository and cd into its directory
  2. make will trigger the Golang build

The provided GNUmakefile defines additional commands generally useful during development, like for running tests, generating documentation, code formatting and linting. Taking a look at it's content is recommended.

Testing

In order to test the provider, you can run

  • make test to run provider tests
  • make testacc to run provider acceptance tests

It's important to note that acceptance tests (testacc) will actually spawn terraform and the provider. Read more about they work on the official page.

Generating documentation

This provider uses terraform-plugin-docs to generate documentation and store it in the docs/ directory. Once a release is cut, the Terraform Registry will download the documentation from docs/ and associate it with the release version. Read more about how this works on the official page.

Use make generate to ensure the documentation is regenerated with any changes.

Using a development build

If running tests and acceptance tests isn't enough, it's possible to set up a local terraform configuration to use a development builds of the provider. This can be achieved by leveraging the Terraform CLI configuration file development overrides.

First, use make install to place a fresh development build of the provider in your ${GOBIN} (defaults to ${GOPATH}/bin or ${HOME}/go/bin if ${GOPATH} is not set). Repeat this every time you make changes to the provider locally.

Then, setup your environment following these instructions to make your local terraform use your local build.

Testing GitHub Actions

This project uses GitHub Actions to realize its CI.

Sometimes it might be helpful to locally reproduce the behaviour of those actions, and for this we use act. Once installed, you can simulate the actions executed when opening a PR with:

# List of workflows for the 'pull_request' action
$ act -l pull_request

# Execute the workflows associated with the `pull_request' action 
$ act pull_request

Releasing

The release process is automated via GitHub Actions, and it's defined in the Workflow release.yml.

Each release is cut by pushing a semantically versioned tag to the default branch.

License

Mozilla Public License v2.0

terraform-provider-null's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-provider-null's Issues

How to use version 3.1.0 ?

Terraform Version

Terraform v0.14.7

Affected Resource(s)

null_resource

If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this.

Terraform Configuration Files

terraform {
  required_providers {
    null = {
      source  = "hashicorp/null"
      version = "3.1.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "3.1.0"
    }
  }
}

Debug Output

Error: Failed to query available provider packages

Could not retrieve the list of available versions for provider
hashicorp/random: no available releases match the given constraints ~> 2.2,
3.1.0


Error: Failed to query available provider packages

Could not retrieve the list of available versions for provider hashicorp/null:
no available releases match the given constraints ~> 2.1, 3.1.0

Expected Behavior

Terraform should be able to download version 3.1.0 of null provider as the current registry release

Actual Behavior

The maximum version of null provider terraform can install is 2.1.2

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform init

Please make a 2.2.0 release

Hello, the null provider has been updated to use the new tf sdk, but that is not yet reflected in a release. Could one be cut?

Cant use provider on a null_resource

This issue was originally opened by @gtmtech as hashicorp/terraform#12916. It was migrated here as part of the provider split. The original body of the issue is below.


Terraform 0.8.7

a null_resource doesnt support provider. How frustrating!

So when terraform doesnt support some aws functionality which I could do with a local-exec of aws cli stuff, then I have to all kinds of equivalent sts assume-role stuff first, because terraform cant supply provider based creds in the environment prior to running the null_resource.

I would assume this is a simple fix?

Provider produced inconsistent final plan

Terraform Version

Terraform v0.13.0-rc1

  • provider registry.terraform.io/hashicorp/aws v3.1.0
  • provider registry.terraform.io/hashicorp/external v1.2.0
  • provider registry.terraform.io/hashicorp/helm v1.2.4
  • provider registry.terraform.io/hashicorp/kubernetes v1.12.0
  • provider registry.terraform.io/hashicorp/null v2.1.2
  • provider registry.terraform.io/terraform-providers/gitlab v2.11.0

We use v0.13 as we need depends_on to work with modules (something that has been made available in v0.13).

Affected Resource(s)

  • null_resource

Terraform Configuration Files

resource "helm_release" "ingress" {
  count = var.ingress == null ? 0 : 1

  name             = "nginx-ingress"
  namespace        = "nginx-ingress"
  create_namespace = true
  repository       = "https://kubernetes-charts.storage.googleapis.com"
  chart            = "nginx-ingress"
  version          = "1.41.2"

  values = [
    <<-EOT
      # some YAML configuration
    EOT
  ]
}

resource "null_resource" "wait_for_elb" {
  count = var.ingress == null ? 0 : 1

  triggers = {
    chart     = helm_release.ingress.0.metadata[0].chart
    name      = helm_release.ingress.0.metadata[0].name
    namespace = helm_release.ingress.0.metadata[0].namespace
    version   = helm_release.ingress.0.metadata[0].version
    values    = helm_release.ingress.0.metadata[0].values
  }

  provisioner "local-exec" {
    command = <<-EOT
      timeout 300 sh -c 'while true; do
        grep "elb.eu-west-1.amazonaws.com" <<<$(
          kubectl -n ${self.triggers.namespace} \
            get service ${self.triggers.name}-controller \
            -o jsonpath="{.status.loadBalancer.ingress[0].hostname}"
          )
        if [ $? -eq 0 ]; then
          break
        else
          exit 1
        fi
        sleep 1
      done' || false
    EOT
  }
}

Expected Behavior

The null_resource should have been triggered (as some values in the trigger block changed), and it should have waited until the Helm package was installed.

Actual Behavior

Terraform gave the following error:

Error: Provider produced inconsistent final plan

When expanding the plan for module.cluster.null_resource.wait_for_elb[0] to
include new values learned so far during apply, provider
"registry.terraform.io/hashicorp/null" produced an invalid new value for
.triggers["values"]: was
cty.StringVal("{\"controller\":{\"config\":{\"server-snippet\":\"listen
8000;\\nif ( $server_port = 80 ) {\\n  return 308
https://$host$request_uri;\\n}\\n\",\"ssl-redirect\":\"false\"},\"containerPort\":{\"http\":80,\"https\":443,\"special\":8000},\"service\":{\"annotations\":{\"service.beta.kubernetes.io/aws-load-balancer-backend-protocol\":\"tcp\",\"service.beta.kubernetes.io/aws-load-balancer-ssl-cert\":\"arn:aws:acm:eu-west-1:<redacted>\",\"service.beta.kubernetes.io/aws-load-balancer-ssl-ports\":\"443\",\"service.beta.kubernetes.io/aws-load-balancer-type\":\"nlb\"},\"targetPorts\":{\"http\":\"http\",\"https\":\"special\"}}}}"),
but now cty.StringVal("{\"controller\":{\"config\":{\"http-snippet\":\"server
{\\n  listen 2443;\\n  return 308
https://$host$request_uri;\\n}\\n\",\"proxy-real-ip-cidr\":\"<redacted>\",\"ssl-redirect\":\"false\",\"use-forwarded-headers\":\"true\"},\"containerPort\":{\"http\":80,\"https\":443,\"tohttps\":2443},\"extraArgs\":{\"disable-catch-all\":null},\"service\":{\"annotations\":{\"service.beta.kubernetes.io/aws-load-balancer-backend-protocol\":\"http\",\"service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout\":\"60\",\"service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled\":\"true\",\"service.beta.kubernetes.io/aws-load-balancer-ssl-cert\":\"arn:aws:acm:eu-west-1:<redacted>\",\"service.beta.kubernetes.io/aws-load-balancer-ssl-ports\":\"https\",\"service.beta.kubernetes.io/aws-load-balancer-type\":\"nlb\"},\"externalTrafficPolicy\":\"Local\",\"targetPorts\":{\"http\":\"tohttps\",\"https\":\"http\"},\"type\":\"LoadBalancer\"}}}").

This is a bug in the provider, which should be reported in the provider's own
issue tracker.


Error: Provider produced inconsistent final plan

When expanding the plan for module.cluster.null_resource.wait_for_elb[0] to
include new values learned so far during apply, provider
"registry.terraform.io/hashicorp/null" produced an invalid new value for
.triggers["version"]: was cty.StringVal("1.39.0"), but now
cty.StringVal("1.41.2").

As the output shows both the values and version fields were changed in the Helm resource. Yet, it is not clear to me why this leads to the experienced failure. Re-running terraform seems to solve the issue (provided no more changes are made to the Helm resource). But, I believe no error should happen in the first place.

Secrets are not hidden if provisioner fails

Terraform CLI and Provider Versions

Terraform v1.1.7
on windows_amd64

  • provider registry.terraform.io/hashicorp/azuread v2.18.0
  • provider registry.terraform.io/hashicorp/azurerm v2.95.0
  • provider registry.terraform.io/hashicorp/null v3.1.0
  • provider registry.terraform.io/hashicorp/random v3.1.0

Terraform Configuration

resource "random_password" "password" {
  length      = 16
  special     = false
  lower       = true
  number      = true
  upper       = true
  min_lower   = 1
  min_numeric = 1
  min_upper   = 1
}

resource "null_resource" "sql_login" {

  triggers = {
    always_run = timestamp()
  }

  provisioner "local-exec" {
    command     = <<EOT
      ${path.module}/scripts/AddSqlLogin.ps1 `
        -SqlServerName "${var.sql_server_name}" `
        -AdminUserName "${var.admin_username}" `
        -AdminPassword "${var.admin_password}" `
        -LoginName "${var.login_name}" `
        -LoginPassword "${random_password.password.result}"
    EOT
    interpreter = ["powershell", "-Command"]
  }
}

Expected Behavior

If the script AddSqlLogin.ps1 cannot be found I should get an error telling me it cannot be found. Any secrets in the error should be overwritten with stars '*'.

Actual Behavior

I get the following error, with the passwords visible :

│ Error: local-exec provisioner error

│ with module.server_logins["APIuser"].null_resource.sql_login,
│ on smart-infrastructure-terraform-modules/common_modules/azure/databases/pwsh_sql_server_login/main.tf line 19, in resource "null_resource" "sql_login":
│ 19: provisioner "local-exec" ***

│ Error running command '
│ smart-infrastructure-terraform-modules/common_modules/azure/databases/pwsh_sql_server_login/scripts/AddSqlLogin.ps1
│ -SqlServerName "reliability-staging-global.database.windows.net"
│ -AdminUserName "smart_admin" │ -AdminPassword "<actual password was visible here>"
│ -LoginName "APIuser" `
│ -LoginPassword ""
│ ': exec: "powershell": executable file not found in $PATH. Output:

Steps to Reproduce

  1. terraform apply

How much impact is this issue causing?

Low

Logs

No response

Additional Information

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Create provider design doc

Maintenance of the standard library providers prioritises stability and correctness relative to the provider's intended feature set. Create a design document describing this feature set, and any other design considerations which influence the architecture of the provider and what can and cannot be added to it.

Accept Terraform State Change Only Feature

This issue was originally opened by @bernadinm as hashicorp/terraform#15882. It was migrated here as a result of the provider split. The original body of the issue is below.


Terraform Version

Terraform v0.10.2

Terraform Configuration Files

-/+ null_resource.agent[0] (new resource required)
      triggers.%:                       "2" => "2"
      triggers.cluster_instance_ids:    "8448795101147796675" => "3512162904296110545" (forces new resource)
      triggers.current_ec2_instance_id: "i-0245ce379c2996374" => "i-0245ce379c2996374"

-/+ null_resource.agent[1] (new resource required)
      triggers.%:                       "2" => "2"
      triggers.cluster_instance_ids:    "8448795101147796675" => "3512162904296110545" (forces new resource)
      triggers.current_ec2_instance_id: "i-0a514ecc7910b3f2e" => "i-0a514ecc7910b3f2e"

-/+ null_resource.public-agent (new resource required)
      triggers.%:                       "2" => "2"
      triggers.cluster_instance_ids:    "8448795101147796675" => "3512162904296110545" (forces new resource)
      triggers.current_ec2_instance_id: "i-087f9484216ddf542" => "i-087f9484216ddf542"

-/+ null_resource.master[0] (new resource required)
      triggers.%:                       "2" => "2"
      triggers.cluster_instance_ids:    "8448795101147796675" => "3512162904296110545" (forces new resource)
      triggers.current_ec2_instance_id: "i-0ef184494e20dbeb4" => "i-0ef184494e20dbeb4"

-/+ null_resource.master[1] (new resource required)
      triggers.%:                       "2" => "2"
      triggers.cluster_instance_ids:    "8448795101147796675" => "3512162904296110545" (forces new resource)
      triggers.current_ec2_instance_id: "i-0e485d1914ecefeaa" => "i-0e485d1914ecefeaa"

-/+ null_resource.master[2] (new resource required)
      triggers.%:                       "2" => "2"
      triggers.cluster_instance_ids:    "8448795101147796675" => "3512162904296110545" (forces new resource)
      triggers.current_ec2_instance_id: "i-0eef40d9c486c6c1c" => "i-0eef40d9c486c6c1c"

Debug Output

terraform untaint <resource-name> has no effect. Since its trying to make a change, a new option would need to exist.

Ideally, a new feature would be introduced below.

terraform apply --accept-terraform-state-changes-only
terraform apply --accept-terraform-state-changes-only -target=null_resource.master[0] -target= null_resource.public-agent

Panic Output

none

Expected Behavior

What should have happened?

It would be good to have the ability to simply accept the changes of a null_resource. Otherwise a user would attempt to take the desired changes and modify the tfstate file manually which is not ideal.

Actual Behavior

What actually happened?

This command terraform untaint <resource-name> has no effect.

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. Make a change that forces a trigger on a null_resouce
  2. terraform untaint null_resource.<name>
  3. terraform plan
  4. Observe that it still would apply the change physically.

Add updatable attribute

Since external references from destroy provisioners are now deprecated, those who use null_resource to run destroy provisioner as last resort clean up after the actual resource is destroyed will be forced to use triggers to store connection information and other related information. Now changes in connection information or any variables used in destroy provisioner will trigger the destroy command, even though the actual resource is not destroyed. It would be helpful if null resource has updatable attribute that does not triggers resource destruction when changed.

Terraform Version

Terraform v0.13.4

Affected Resource(s)

Please list the resources as a list, for example:

  • null_resource

If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this.

Terraform Configuration Files

resource "null_resource" "destroyer" {
  triggers = {
    ssh_host = var.ssh["host"]
    ssh_port = var.ssh["port"]
    ssh_user = var.ssh["user"]
    ssh_password = var.ssh["password"]
    ssh_private_key = var.ssh["private_key"]
    
    docker_host_base_path = local.docker_host_base_path
    docker_container_name = local.docker_container_name
  }

  connection {
    type        = "ssh"
    host        = self.triggers.ssh_host
    port        = self.triggers.ssh_port
    user        = self.triggers.ssh_user
    password    = self.triggers.ssh_password
    private_key = self.triggers.ssh_private_key
  }

  provisioner "remote-exec" {
    when = destroy
    on_failure = continue
    inline = [
      "mv ${self.triggers.docker_host_base_path} /tmp/destroyed-${self.triggers.docker_container_name}-${timestamp()}",
    ]
  }
}

resource "docker_container" "some_container_that_mount_host_directory_and_write_to_it" {
   depends_on = [ null_resource.destroyer ]
   ...
}

Debug Output

Panic Output

Expected Behavior

Destruction command should not be triggered by changes in connection information

Actual Behavior

Destruction command executed.

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply
  2. update connection information such as password
  3. terraform apply

Important Factoids

References

[Documentation][Web][Usability] Documentation is too wide and requires scrolling

Terraform CLI and Provider Versions

Looking at documentation on the web: https://registry.terraform.io/providers/hashicorp/null/3.1.1/docs/resources/resource
No terraform binary used/involved.
Safari browser on Mac OS
Provider version: 3.1.1

Terraform Configuration

https://registry.terraform.io/providers/hashicorp/null/3.1.1/docs/resources/resource

Expected Behavior

I would like to be able to read the documentation without horizontal scrolling.

Actual Behavior

No matter what scaling and/or aspect ratio I use, the central part of the documentation always requires horizontal scrolling. While at the same time there is tons of white space both left and right.

Steps to Reproduce

  1. open documentation in a browser: https://registry.terraform.io/providers/hashicorp/null/3.1.1/docs/resources/resource
  2. try to read the main part of the documentation (the part with the comment tags)

How much impact is this issue causing?

Low

Logs

No response

Additional Information

I'm sure this can be fixed at code level. No need to involve the web designer. Just re-do the line breaks at or before column 76.

Code of Conduct

  • I agree to follow this project's Code of Conduct

Do not depreciate null_data_source

DeprecationMessage: "The null_data_source was historically used to construct intermediate values to re-use elsewhere " +
"in configuration, the same can now be achieved using locals",

The null_data_source has a use that can not be replaced by current terraform functionality. It provides a proxy depends_on for variables.

module "mymodule" {}

module "grant_access" {
  arg1 = module.mymodule.output1
}

data "null_data_source" "wait_for_access" {
  depends_on = [module.grant_access]
  inputs = {
    input1 = module.mymodule.output2
  }
}

module "myothermodule" {
  arg1 = data.null_data_source.wait_for_access.outputs.input1
}

The alternative to this would be setting depends_on = [module.grant_access] for module.myothermodule which adds a global dependency to all resources within myothermodule rather than only the resources that depend on arg1.

Mac M1 Build

Looking to use Terraform on a M1 Mac. like other providers, this module is missing support it seems for Mac M1 builds.

Terraform Version

v0.15.4

Affected Resource(s)

All

If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this.

Terraform Configuration Files

N/A

Debug Output

│ Error: Incompatible provider version
│
│ Provider registry.terraform.io/hashicorp/null v2.1.2 does not have a
│ package available for your current platform, darwin_arm64.
│
│ Provider releases are separate from Terraform CLI releases, so not all
│ providers are available for all platforms. Other versions of this provider
│ may have different platforms supported.

Expected Behavior

Like other providers that have been updated - this provider should install as normal on Mac M1 hardware

Actual Behavior

Can not use terraform when using this provider on a M1 Mac

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply

proposal: Add trigger without ForceNew: true / allow null_resource update

Proposal

We use the null_resource with a database migration command, that it self is aware of its state. So there are mainly three operations:

  • migrate up
  • migrate down
  • migrate drop

For our case only the first and the last one are relevant. We would like to execute migrate up when ever the terraform apply is executed and migrate drop, if terraform destroy is executed. But this does currently not work, because even a terraform apply would first execute the destroy command (see also the linked issues). Of course, dropping the entire DB in this case is not an option, because we would loose all the data stored in it.

The reason for this is, that currently, the null_resource only supports triggers, that have the ForceNew attribute set to true (see https://github.com/hashicorp/terraform-provider-null/blob/main/internal/provider/resource.go#L25).

I would like to propose an additional trigger (e.g. triggers_update or triggers_soft), that has the ForceNew attribute set to false and therefore would update the resource in place, that is, it would only execute the create action on update, without the prior destroy.

Affected Resource(s)

Please list the resources as a list, for example:

  • null_resource

Terraform Configuration Files

Example with the proposed triggers_update:

resource "null_resource" "test" {
  triggers_update = timestamp()

  provisioner "local-exec" {
    when        = create
    command = "echo create"
  }

  provisioner "local-exec" {
    when        = destroy
    command     = "echo destroy"
  }
}

Expected Behavior

On terraform apply, only the create action is executed. On terraform destroy, the destroy action is executed.

Actual Behavior

Currently this is not possible as pointed out above. The ForceNew causes the destroy action to happen before the create action, if there is already a resource existing.

References

Minor spelling error in null_resource documentation

Hi there,

Just a small error with the documentation for the null_resource.

Affected Resource(s)

  • null_resource Documentation

Spelling error in the following path:

  • docs/resources/resource.md
  provisioner "remote-exec" {
    # Bootstrap script called with private_ip of each node in the clutser
    inline = [
      "bootstrap-cluster.sh ${join(" ", aws_instance.cluster.*.private_ip)}",
    ]
  }

"Cluster" is misspelled as "clutser" in the commented line. Should be the following:

  provisioner "remote-exec" {
    # Bootstrap script called with private_ip of each node in the cluster
    inline = [
      "bootstrap-cluster.sh ${join(" ", aws_instance.cluster.*.private_ip)}",
    ]
  }

Destroy time depends_on missing order on destroying

Hi there,
I have two null_resources create1 and create2 and two destroy time null_resources delete1 and delete2. I want delete1 and delete2 to run when create1 and create2 are deleted when I run terraform destroy. am I wrong in the code or is it by design or bug?

when I run terraform apply I see that create1 ran before create2 which is perfect.

#> terraform apply -auto-approve                                                                                                                  null_resource.create1: Creating...
null_resource.create1: Provisioning with 'local-exec'...
null_resource.create1 (local-exec): Executing: ["pwsh" "-Command" "Write-Output 'Create 1'"]
null_resource.create1 (local-exec): Create 1
null_resource.create1: Creation complete after 5s [id=3984634756973961301]
null_resource.delete1: Creating...
null_resource.create2: Creating...
null_resource.delete1: Creation complete after 0s [id=2672729497423318944]
null_resource.create2: Provisioning with 'local-exec'...
null_resource.create2 (local-exec): Executing: ["pwsh" "-Command" "Write-Output 'Create 2'"]
null_resource.create2 (local-exec): Create 2
null_resource.create2: Creation complete after 4s [id=5236526839634656700]
null_resource.delete2: Creating...
null_resource.delete2: Creation complete after 0s [id=5226889765845627431]

I don't see any timestamp to say what ran first but based on the output and its order, I am thinking this is what the order being followed.

#> terraform destroy -auto-approve                                                                                                                null_resource.create1: Refreshing state... [id=3984634756973961301]
null_resource.create2: Refreshing state... [id=5236526839634656700]
null_resource.delete1: Refreshing state... [id=2672729497423318944]
null_resource.delete2: Refreshing state... [id=5226889765845627431]
null_resource.delete1: Destroying... [id=2672729497423318944]
null_resource.delete2: Destroying... [id=5226889765845627431]
null_resource.delete1: Provisioning with 'local-exec'...
null_resource.delete2: Provisioning with 'local-exec'...
null_resource.delete2 (local-exec): Executing: ["pwsh" "-Command" "Write-Output 'Delete 2'"]
null_resource.delete1 (local-exec): Executing: ["pwsh" "-Command" "Write-Output 'delete 1'"]
null_resource.delete1 (local-exec): delete 1
null_resource.delete2 (local-exec): Delete 2
null_resource.delete1: Destruction complete after 5s
null_resource.delete2: Destruction complete after 5s
null_resource.create2: Destroying... [id=5236526839634656700]
null_resource.create2: Destruction complete after 0s
null_resource.create1: Destroying... [id=3984634756973961301]
null_resource.create1: Destruction complete after 0s

Terraform Version

#> terraform -v
Terraform v0.13.1

  • provider registry.terraform.io/hashicorp/null v3.0.0

Affected Resource(s)

null_resource

If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this.

Terraform Configuration Files

resource null_resource create1 {
    provisioner local-exec {
    command = "Write-Output 'Create 1'"
    interpreter = ["pwsh", "-Command"]
  }
}

resource null_resource create2 {
    provisioner local-exec {
    command = "Write-Output 'Create 2'"
    interpreter = ["pwsh", "-Command"]
  }
  depends_on = [null_resource.create1]
}

resource null_resource delete1 {
    provisioner local-exec {
    when = destroy
    command = "Write-Output 'delete 1'"
    interpreter = ["pwsh", "-Command"]
  }
  depends_on = [null_resource.create1]
}

resource null_resource delete2 {
    provisioner local-exec {
    when = destroy
    command = "Write-Output 'Delete 2'"
    interpreter = ["pwsh", "-Command"]
  }
  depends_on = [null_resource.create2]
}

Debug Output

Please provider a link to a GitHub Gist containing the complete debug output: https://www.terraform.io/docs/internals/debugging.html. Please do NOT paste the debug output in the issue; just paste a link to the Gist.

Panic Output

If Terraform produced a panic, please provide a link to a GitHub Gist containing the output of the crash.log.

Expected Behavior

Terraform should run delete1 after destroying create1 and delete2 after destroying create2 respectively.

Actual Behavior

see output above

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply

Important Factoids

References

Have resource fail on error from remote-exec?

Terraform Version

Terraform v0.11.8

  • provider.aws v1.33.0
  • provider.null v1.0.0
  • provider.random v2.0.0

Affected Resource(s)

Please list the resources as a list, for example:

  • null_resource

Terraform Configuration Files

resource "null_resource" "ServerDsc" {
  count = "${var.ServerSpecs["count"]}"

  triggers = {
    cluster_instance_ids = "${aws_instance.Server.id}"
  }

  connection = {
    type     = "winrm"
    user     = "${var.deployInfo["AdminUsername"]}"
    password = "${var.deployInfo["AdminPassword"]}"
    host     = "${aws_eip.ServerEip.public_ip}"
    timeout  = "10m"
  }

  provisioner "remote-exec" {
    inline = [
      "powershell.exe Invoke-WebRequest -OutFile C:\\dsc.zip -Uri \"https://s3-${var.deployInfo["awsRegion"]}.amazonaws.com/${aws_s3_bucket.deploymentArtifactsBucket.id}/${aws_s3_bucket_object.dscResources.id}\" -UseBasicParsing -ErrorAction Ignore",
      "powershell.exe Expand-Archive -Path C:\\dsc.zip -Destination C:\\dsc -Force",
      "powershell.exe Copy-Item -LiteralPath C:\\dsc\\folder1 -Destination 'C:\\Program Files\\WindowsPowerShell\\Modules\\' -Force -Recurse",
      "powershell.exe Copy-Item -LiteralPath C:\\dsc\\xPendingReboot -Destination 'C:\\Program Files\\WindowsPowerShell\\Modules\\' -Force -Recurse",
      "powershell.exe C:\\dsc\\content.ps1 -webAdaptorUrl \"https://s3-${var.deployInfo["awsRegion"]}.amazonaws.com/${aws_s3_bucket.deploymentArtifactsBucket.id}/${aws_s3_bucket_object.webAdaptorInstaller.id}\" -serverLicenseUrl \"https://s3-${var.deployInfo["awsRegion"]}.amazonaws.com/${aws_s3_bucket.deploymentArtifactsBucket.id}/${aws_s3_bucket_object.serverLicense.id}\" -sslCertificateUrl \"https://s3-${var.deployInfo["awsRegion"]}.amazonaws.com/${aws_s3_bucket.deploymentArtifactsBucket.id}/${aws_s3_bucket_object.sslCertificate.id}\" -sslCertificatePassword \"${var.deployInfo["pfxPassword"]}\" -externalDNS \"${var.deployInfo["externalDNS"]}\" -Version \"${var.deployInfo["Version"]}\" -serviceAccountCredential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList \"${var.deployInfo["serviceAccountUsername"]}\",(ConvertTo-SecureString -String \"${var.deployInfo["serviceAccountPassword"]}\" -AsPlainText -Force)) -gocAdminCredential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList \"${var.deployInfo["gocAdminUsername"]}\",(ConvertTo-SecureString -String \"${var.deployInfo["gocAdminPassword"]}\" -AsPlainText -Force)) -psaCredential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList \"${var.deployInfo["psaUsername"]}\",(ConvertTo-SecureString -String \"${var.deployInfo["psaPassword"]}\" -AsPlainText -Force)) -IsAws $true",
    ]
  }
}

Actual Behavior

The resource completes successfully from the Terraform perspective but the DSC configuration fails on the instance side.

Important Factoids

As this is a generic resource for executing various tasks, I am not sure what is even possible with getting the resource to fail if the remote action throws errors, etc. Essentially, I would like to be able to use the null resource to push dsc configurations that are too complicated for user_data because I need to get a successful confirmation from one machine before starting the configuration on another machine as it relies on the first machine being up and configured.

incompatible with Terraform v0.12

Hi there,

The current release of Null provider is not compatible with Terraform v0.12 release.

Terraform Version

Terraform v0.12.0

Affected Resource(s)

Null Resource and Data Source

Terraform Configuration Files

provider "null" {
	version = "~> 2.1"
}

resource "null_resource" "anything" {
	provisioner "local-exec" {
		command = "env"
	}
}

Debug Output

$ terraform 0.12checklist
After analyzing this configuration and working directory, we have identified some necessary steps that we recommend you take before upgrading to Terraform v0.12:

- [ ] Upgrade provider "null" to version 2.1.2 or newer.

  No currently-installed version is compatible with Terraform 0.12. To upgrade, set the version constraint for this provider as follows and then run `terraform init`:

      version = "~> 2.1.2"

Taking these steps before upgrading to Terraform v0.12 will simplify the upgrade process by avoiding syntax errors and other compatibility problems.

Expected Behavior

Terraform downloads a version 0.12 compatible release.

Actual Behavior

$ terraform init
Provider "null" v1.0.0 is not compatible with Terraform 0.12.0.

Provider version 2.1.0 is the earliest compatible version. Select it with
the following version constraint:

	version = "~> 2.1"

Terraform checked all of the plugin versions matching the given constraint:
    ~> 1.0

Consult the documentation for this provider for more information on
compatibility between provider and Terraform versions.

Setting provider version to init suggested ~> 2.1 as above configuration file example resulted error,

$ terraform init
No provider "null" plugins meet the constraint "~> 1.0,~> 2.1".

The version constraint is derived from the "version" argument within the
provider "null" block in configuration. Child modules may also apply
provider version constraints. To view the provider versions requested by each
module in the current configuration, run "terraform providers".

To proceed, the version constraints for this provider must be relaxed by
either adjusting or removing the "version" argument in the provider blocks
throughout the configuration.

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. upgrade Terraform to v0.12
  2. terraform init

Null provider tirggers always

data "external" "artifact_info" {
  program = ["bash", "${path.module}/parse_artifact_info.sh"]

  query {
    info_file = "${local.artifact_info_file}"
  }

  depends_on = ["local_file.artifact_info"]
}

resource "null_resource" "get_artifact" {
  triggers {
    key = "${data.external.artifact_info.result["md5"]}"
  }

  provisioner "local-exec" {
    command = "curl -k  -L '${data.external.artifact_info.result["url"]}' -o ${path.module}/tmp/${var.artifact}.zip"
  }

  depends_on = ["data.external.artifact_info"]
}

terraform run

-/+ null_resource.get_artifact (new resource required)
      id:                    "8272426212213023344" => <computed> (forces new resource)
      triggers.%:            "1" => <computed> (forces new resource)
      triggers.key:       "b0bac262cc4171fcda8557562ff79b21" => "" (forces new resource)

Notice the triggers.key does not show "computed" other than empty, this triggers my local-exec provisioner to run everytime.

key = "true" outputs as key = 1

Terraform Version

0.11.14

Affected Resource(s)

  • null_data_source

Terraform Configuration Files

provider "null" {
  version = "~> 2.1"
}

data "null_data_source" "asg_tags" {
  count  = "${length(keys(local.tags))}"

  inputs = {
    key                 = "${element(keys(local.tags), count.index)}"
    value               = "${element(values(local.tags), count.index)}"
    propagate_at_launch = "true"
  }
}
# also tried:
# propagate_at_launch = true (no quotes)
#
# inputs = "${map("key", "${element(keys(local.tags), count.index)}",
#             "value", "${element(values(local.tags), count.index)}",
#             "propagate_at_launch", "true")}"

locals {
  tags = {
    A = "aaaa"
    B = "bbbb"
  }

  asg_tags = ["${concat(list(
    map("key", "Name",
        "value", "ECS node",
        "propagate_at_launch", "true")),
    data.null_data_source.asg_tags.*.outputs)}"]
}

output "asg_tags" {
  value = "${local.asg_tags}"
}

Debug Output

https://gist.github.com/evansj/cae39bc7fa0fa69bd64a4eb36e0db5ce

Expected Behavior

Outputs:

asg_tags = [
    {
        key = Name,
        propagate_at_launch = true,
        value = ECS node
    },
    {
        key = A,
        propagate_at_launch = true,
        value = aaaa
    },
    {
        key = B,
        propagate_at_launch = true,
        value = bbbb
    }

Actual Behavior

Outputs:

asg_tags = [
    {
        key = Name,
        propagate_at_launch = true,
        value = ECS node
    },
    {
        key = A,
        propagate_at_launch = 1,
        value = aaaa
    },
    {
        key = B,
        propagate_at_launch = 1,
        value = bbbb
    }

Steps to Reproduce

  1. Copy the above sample code into a .tf file
  2. terraform init
  3. terraform apply

References

[3.2.0] null_resource id becomes constant, semi-random and unaffected by changing of triggers values

Terraform CLI and Provider Versions

Terraform v1.2.3
on linux_amd64

  • provider registry.terraform.io/hashicorp/aws v4.39.0
  • provider registry.terraform.io/hashicorp/external v2.2.3
  • provider registry.terraform.io/hashicorp/null v3.2.0

Terraform Configuration

resource "null_resource" "build-trigger" {
  triggers = {
    test-trigger-value = "qwertyuiop12345678"
    source-image-id   = data.aws_ami.latest-amazon-ecs-optimized.id
    assets-dir-hash   = data.external.assets-dir-hash.result["sha256"]
    packer-definition = filesha256("./packer.toml")
  }
}

Expected Behavior

null_resource.[resource-name].id is random and changes varies with triggers, as before 3.2.0 version of null provider.

Actual Behavior

null_resource.[resource-name].id value is constant (5577006791947779410 for first null_resource instance in module ,as I see), and doesn't change after changed triggers value or recreate of resource.

Steps to Reproduce

Change any null_resource trigger value and verify that the resource ID stays the same after apply.

How much impact is this issue causing?

Low

Logs

No response

Additional Information

I see this as a backward compatibility breaking change, but deployed in minor provider update.
In my case this breaks unique resource naming, which depends on triggers value.
I realize there is a way around this with a random_id from a random provider and that will be my solution, but this "quiet" change has caused some hassle and troubleshooting.

Code of Conduct

  • I agree to follow this project's Code of Conduct

Failure for go get github.com/hashicorp/terraform-provider-null

Expected Behavior

Should download and successfully build terraform-provider-null

Actual Behavior

Getting below error:

github.com/hashicorp/terraform-provider-null imports
        github.com/terraform-providers/terraform-provider-null/null imports
        github.com/hashicorp/terraform/helper/schema: cannot find module providing package github.com/hashicorp/terraform/helper/schema

What actually happened?

[root@rajalakshmi-workspace ~]# go get github.com/hashicorp/terraform-provider-null
go: downloading github.com/hashicorp/terraform-provider-null v1.0.0
go: downloading github.com/terraform-providers/terraform-provider-null v1.0.0
go: downloading github.com/hashicorp/terraform v0.15.0
go: downloading github.com/hashicorp/go-plugin v1.4.0
go: downloading github.com/zclconf/go-cty v1.8.1
go: downloading google.golang.org/grpc v1.31.1
go: downloading github.com/hashicorp/go-hclog v0.15.0
go: downloading github.com/mitchellh/panicwrap v1.0.0
go: downloading github.com/golang/protobuf v1.4.3
go: downloading google.golang.org/protobuf v1.25.0
go: downloading github.com/hashicorp/go-multierror v1.1.1
go: downloading github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f
go: downloading github.com/hashicorp/hcl/v2 v2.9.1
go: downloading github.com/hashicorp/errwrap v1.1.0
go: downloading github.com/agext/levenshtein v1.2.2
go: downloading github.com/apparentlymart/go-versions v1.0.1
go: downloading github.com/fatih/color v1.7.0
go: downloading github.com/mattn/go-colorable v0.1.4
go: downloading github.com/mattn/go-isatty v0.0.12
go: downloading github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d
go: downloading github.com/mitchellh/go-testing-interface v1.0.0
go: downloading github.com/oklog/run v1.0.0
go: downloading golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
go: downloading github.com/vmihailenco/msgpack v3.3.3+incompatible
go: downloading golang.org/x/text v0.3.5
go: downloading github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734
go: downloading github.com/vmihailenco/msgpack/v4 v4.3.12
go: downloading google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d
go: downloading github.com/hashicorp/go-version v1.2.1
go: downloading github.com/spf13/afero v1.2.2
go: downloading github.com/google/go-cmp v0.5.2
go: downloading github.com/zclconf/go-cty-yaml v1.0.2
go: downloading github.com/hashicorp/go-retryablehttp v0.5.2
go: downloading golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
go: downloading golang.org/x/mod v0.3.0
go: downloading golang.org/x/sys v0.0.0-20201119102817-f84b799fce68
go: downloading github.com/apparentlymart/go-textseg v1.0.0
go: downloading github.com/mitchellh/go-wordwrap v1.0.0
go: downloading github.com/vmihailenco/tagparser v0.1.1
go: downloading google.golang.org/appengine v1.6.6
go: downloading github.com/apparentlymart/go-cidr v1.1.0
go: downloading github.com/bmatcuk/doublestar v1.1.5
go: downloading github.com/apparentlymart/go-textseg/v13 v13.0.0
go: downloading github.com/google/uuid v1.2.0
go: downloading github.com/hashicorp/go-uuid v1.0.1
go: downloading github.com/mitchellh/go-homedir v1.1.0
go: downloading github.com/hashicorp/go-cleanhttp v0.5.1
go: downloading golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
github.com/hashicorp/terraform-provider-null imports
        github.com/terraform-providers/terraform-provider-null/null imports
        github.com/hashicorp/terraform/helper/schema: cannot find module providing package github.com/hashicorp/terraform/helper/schema
[root@rajalakshmi-workspace ~]# 

Steps to Reproduce

  1. go get github.com/hashicorp/terraform-provider-null

References

This started occurring after the release of terraform 0.15
https://github.com/hashicorp/terraform/releases/tag/v0.15.0

null_data_source documentation examples are incorrect

This issue was originally opened by @ThisGuyCodes as hashicorp/terraform#17440. It was migrated here as a result of the provider split. The original body of the issue is below.


I'm not sure if this is where documentation issues should be reported, but here we go:

Terraform Version

Terraform v0.11.3
+ provider.null v1.0.0

Terraform Configuration Files

data "null_data_source" "values" {
  inputs = {
    something = "value"
  }
}

output "something" {
  value = "${data.null_data_source.values["something"]}"
}

Expected Behavior

plan succeeds with no changes

Actual Behavior

Error: Error loading REDACTED/this.tf: Error reading config for output something: data.null_data_source.values: data variables must be four parts: data.TYPE.NAME.ATTR in:

${data.null_data_source.values["something"]}

Steps to Reproduce

Run terraform init and terraform plan against the single provided file (above)

Additional Context

Example usage here:
https://www.terraform.io/docs/providers/null/data_source.html
uses this syntax:

data.null_data_source.<name>["<key>"]

(as is used in the sample code I provide above). When in fact the correct syntax (as can be figured out by reading the attribute reference and ignoring the examples) is:

data.null_data_source.<name>.outputs["<key>"]

Unable to create local file

Hi there,

I am unable to use null_resource to create a local file (it works great for creating a file on an instance). The documentation seems to imply that it is possible, as does hashicorp/terraform#2342

Terraform Version

Terraform v0.10.6

Terraform Configuration Files

data "template_file" "file" {
  template = "${file("file.template.txt")}"
  vars {
    name = "Bob"
  }
}

resource "null_resource" "local_file" {
  provisioner "file" {
    content     = "${data.template_file.file.rendered}"
    destination = "${path.root}/file.txt"
  }
}

file.template.txt:

Hello ${name}!

Expected Behavior

A local file named file.txt should be created.

Actual Behavior

It eventually fails with this error:

1 error(s) occurred:

* null_resource.local_file: 1 error(s) occurred:

* dial tcp :22: getsockopt: connection refused

Steps to Reproduce

Use the terraform config above and run terraform apply.

Allow any configuration option to null_resource

This issue was originally opened by @mildred as hashicorp/terraform#15213. It was migrated here as part of the provider split. The original body of the issue is below.


Hi there,

null_resource should accept any configuration. Currently I cannot write the following without having a complain from terraform because config is not accepted:

resource "null_resource" "foo" {
  triggers {
    change = "${var.change}"
  }
  config = "${var.config}"
  lifecycle {
    ignore_changes = ["config"]
  }
}
output "config" {
  value = "${null_resource.foo.config}"
}

This snippet, if it worked, would be very useful. When var.change changes, the null_resource would save within the tfstate the value of var.config and as long as var.change doesn't change any more, we can still acccess the saved version of var.config through null_resource.foo.config. This is a memory unit.

Additionally, it would be super useful if we could have a special interpolation syntax to access the previous value of a property (what was in the tfstate before the run).

Currently, I'm using random_pet instead to serve as a memory unit. It works like a null_resource but wit keepers instead of triggers. I have:

// This is a random value that changes each time the cluster size change
// it is important that in time, for two same cluster_size values, this will
// take different output values
resource "random_pet" "cluster_size" {
  keepers {
    token = "${var.cluster_size}"
  }
}

// Use random_pet as a memory.
// The reset condition is when the first coreos instance is created (or
// recreated as a new resource)
// The saved values are
// - length: the cluster size at bootstrap
// - prefix: the random_pet.cluster_size value
// it is possible to know if we are bootstrapping if the prefix saved here is
// identical to the random_pet.cluster_size value. Also, only the cluster size
// at bootstrap will be saved.
resource "random_pet" "memory" {
  keepers {
    token = "${element(aws_instance.coreos.*.id, 0)}"
  }
  length = "${var.cluster_size}"
  prefix = "${random_pet.cluter_size.id}"
  lifecycle {
    ignore_changes = ["prefix", "length"]
  }
}

output "consul_bootstrap_expect" {
  value = "${(random_pet.memory.length == var.size && random_pet.memory.prefix == random_pet.cluster_size.id) ? "-bootstrap-expect=${random_pet.memory.length}" : ""}"
}

Terraform plan keep suggesting in-place changes for Null resource.

Terraform CLI and Provider Versions

Terraform v1.3.1, darwin_amd64

provider registry.terraform.io/hashicorp/null v3.1.1

Terraform Configuration

locals {
  reboot_script = [
    "sudo reboot &",
  ]
}

resource "null_resource" "node_reboot" {
  triggers = {
    private_ip    = aws_instance.node.private_ip
    user          = local.node_config.instance_user
    password      = local.node_config.instance_user_password
    reboot_script = md5(join(",", local.reboot_script))
  }
  connection {
    host                = local.connection.host
    user                = local.connection.user
    password            = local.connection.password
    private_key         = local.connection.private_key
    bastion_host        = local.connection.bastion_host
    bastion_user        = local.connection.bastion_user
    bastion_private_key = local.connection.bastion_private_key
    timeout             = local.connection.timeout
  }
  provisioner "remote-exec" {
    inline = local.reboot_script
  }
  depends_on = [null_resource.disk1_data, null_resource.disk2_mount]
}

Expected Behavior

The null_resource should not report for update (or even replacement) after terraform apply.

Actual Behavior

The terraform plan keeps on showing following as part of the plan output even when tf apply is completed.

# module.module1.null_resource.node_reboot will be updated in-place
~ resource "null_resource" "node_reboot" {
      id       = "1931086068078653693"
      # (1 unchanged attribute hidden)
}

There seems to be 3 issues I am facing.

  1. The null_resource should not report any changes.
  2. Even if there are changes it should report the changes as replacement rather than in-place changes.
  3. The terraform plan should provide information about what is being changed (the plan output does not show any change to be done - as seen above. Not sure what is being changed in-place here).

Any subsequent apply fails in this case as null_resource does not support in-place changes.

Steps to Reproduce

  1. terraform apply

How much impact is this issue causing?

High

Logs

No response

Additional Information

Do let me know if any other information is required.

Code of Conduct

  • I agree to follow this project's Code of Conduct

Bump Expected Minimum Go Version to 1.18

Terraform CLI and Provider Versions

TF: v1.2.7
Provider: v3.1.1

Use Cases or Problem Statement

Following the Go support policy and given the ecosystem availability of the latest Go minor version, it's time to upgrade. This will ensure that this project can use recent improvements to the Go runtime, standard library functionality, and continue to receive security updates.

Proposal

  • Run the following commands to upgrade the Go module files and automatically fix outdated Go code:
go mod edit -go=1.18
go mod tidy
go fix
  • Ensure any GitHub Actions workflows (.github/workflows/*.yml) use 1.19 in place of any 1.18 and 1.18 in place of any 1.17 or earlier
  • Ensure the README or any Contributing documentation notes the Go 1.18 expected minimum
  • (Not applicable to all projects) Ensure the .go-version is at least 1.18 or later

How much impact is this issue causing?

Low

Additional Information

References

Code of Conduct

  • I agree to follow this project's Code of Conduct

Migrate Documentation to terraform-plugin-docs

The "standard library" Terraform Providers should implement nascent provider development tooling to encourage consistency, foster automation where possible, and discover bugs/enhancements to that tooling. To that end, this provider's documentation should be switched to terraform-plugin-docs, including:

  • Migrating directory structures and files as necessary
  • Enabling automation for documentation generation (e.g. make gen or go generate ./...)
  • Enabling automated checking that documentation has been re-generated during pull request testing (e.g. no differences)

Allow defining triggers that are sensitive information

Terraform Version

Terraform v0.12.20

  • provider.null v2.1.2

Affected Resource(s)

  • null_resource

Terraform Configuration Files

variable "mysecret" {
  type = string
}

resource null_resource example {
  triggers = {
    secret = var.mysecret
  }

  provisioner "local-exec" {
    command = "echo Create"
    environment = {
      SECRET = self.triggers.mysecret
    }
  }
  
  provisioner "local-exec" {
    command = "echo Destroy"
    environment = {
      SECRET = self.triggers.mysecret
    }
  }
}

Debug Output

❯ terraform apply
var.mysecret
  Enter a value: supersecret


An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # null_resource.example will be created
  + resource "null_resource" "example" {
      + id       = (known after apply)
      + triggers = {
          + "secret" = "supersecret"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions in workspace "play"?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: no

Apply cancelled.

Expected Behavior

A way to provide sensitive values as triggers, so that the plan does only print (sensitive) and not the actual value of a sensitive trigger.

Actual Behavior

No way to define sensitive triggers.

Steps to Reproduce

  1. terraform apply

Important Factoids

The null_resource should also take a sensitive_triggers map that is obfuscated in the plan output.

Other providers, like the local provider use a similar approach:
https://www.terraform.io/docs/providers/local/r/file.html

Migrate acceptance testing to terraform-plugin-testing

Terraform CLI and Provider Versions

N/A

Use Cases or Problem Statement

A new terraform-plugin-testing Go module has been released. New testing functionality will only land in terraform-plugin-testing and this should allow most providers to stop depending directly on terraform-plugin-sdk.

Proposal

Follow the migration guide: https://developer.hashicorp.com/terraform/plugin/testing/migrating

How much impact is this issue causing?

Low

Additional Information

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

null_data_source with count not getting referenced correctly

I'm computing a ListMap with null_data_source with count and inputs, to create a ListMap with specific keys and values from a list of hostnames and IP addresses, based on a dynamic created VMs.

My null_data_source looks like this:

Then I pass the outputs as a nodes variable into a module where I reference them in a resource. When I output the nodes inside the module, I get the correct output, but the resource doesn't.

data "null_data_source" rke_nodes {
  count = "${var.node_count}"

  inputs = {
    address = "${element(module.cluster_nodes.node_ips, count.index)}"
    user    = "${var.ssh_username}"
    roles   = "controlplane,etcd,worker"
    ssh_key = "${var.ssh_private_key}"
  }
}

module rke {
  source = "./rke"

  ssh_username    = "${var.ssh_username}"
  ssh_private_key = "${var.ssh_private_key}"

  cluster_dns_fqdn = "${var.cluster_dns_fqdn}"

  nodes      = ["${data.null_data_source.rke_nodes.*.outputs}"]
}

Then inside the rke module I use the nodes variable like the following:

resource "rke_cluster" rke_cluster {
   nodes = ["${var.nodes}"]

   ingress = {
     provider = "none"
   }
 }

The error I get:

Error: module.vsphere.module.rancher.module.rancher_cluster.module.rke.rke_cluster.rke_cluster: "nodes.0.address": required field is not set

But when I output the nodes.0.address and read it with terraform output command I get the IP address expected. See below:

output ip {
    value = "${lookup(var.nodes[0], "address")}"
}

$ terraform output -module=rke ip
192.168.176.55

How can this be solved?

Upgrade Provider

Terraform CLI and Provider Versions

Terraform v1.2.4
Provider v3.1.1

Use Cases or Problem Statement

As part of the utility provider upgrade, we need to add/update the following:

  1. Guidance in the form of CONTRIBUTING.md, README.mdandSUPPORT.md` either needs to be added or updated.
  2. The 'Makefile' needs to be updated
  3. There is currently no linting set-up in the null provider
  4. The null provider makes use of deprecated fields, types and/or functions (e.g., Create rather than CreateContext).

Proposal

  1. add or update CONTRIBUTING.md, README.md and SUPPORT.md and use a consistant format to other utlitity providers. Use the following examples in the TLS provider as template
  2. Update 'Makefile' - An example of a recently updated can be found in the http provider
  3. Setup linting with golangci-lint - An example can be found in the http provider.
  4. Replace all uses of deprecated fields, types and or functions.
    For instance, replace usage of Create with CreateContext.

How much impact is this issue causing?

Low

Additional Information

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Terraform framework change

Terraform CLI and Provider Versions

The terraform null provider 3.2.0 is causing issues when upgrading from 0.11 to 0.12.
Exception Error in plan -
Error: Unable to Read Previously Saved State for UpgradeResourceState

There was an error reading the saved resource state using the current resource
schema.

If this resource state was last refreshed with Terraform CLI 0.11 and earlier,
it must be refreshed or applied with an older provider version first. If you
manually modified the resource state, you will need to manually modify it to
match the current resource schema. Otherwise, please report this to the
provider developer:

flatmap states cannot be unmarshaled, only states written by Terraform 0.12
and higher can be unmarshaled

With the 3.1.1 provider this didn't occur. I had the null provider pinned to all 3.0.0 versions since I didn't realize that changing the framework would be considered a minor change rather than a major change.

Terraform Configuration

resource "null_resource" "notification" {
  count = var.multi_region == false ? 1 : 0
  triggers = {
    crit = module.aws-cams-pagerduty.pagerduty_service_integration_Critical_integration_key
    warn = module.aws-cams-pagerduty.pagerduty_service_integration_Warning_integration_key
    back = module.aws-cams-pagerduty.pagerduty_service_integration_Backup_integration_key
    secu = module.aws-cams-pagerduty.pagerduty_service_integration_Security_integration_key
    ctop = module.aws-cams-notification-primary.aws_sns_topic_CMSCriticalAlarmTriggeredTopic
    wtop = module.aws-cams-notification-primary.aws_sns_topic_CMSWarningAlarmTriggeredTopic
  }
}

Expected Behavior

3.2.0 should be able to upgrade a 0.11 statefile

Actual Behavior

Throws error

Exception Error in plan -
Error: Unable to Read Previously Saved State for UpgradeResourceState

There was an error reading the saved resource state using the current resource
schema.

If this resource state was last refreshed with Terraform CLI 0.11 and earlier,
it must be refreshed or applied with an older provider version first. If you
manually modified the resource state, you will need to manually modify it to
match the current resource schema. Otherwise, please report this to the
provider developer:

flatmap states cannot be unmarshaled, only states written by Terraform 0.12
and higher can be unmarshaled

Steps to Reproduce

  1. have statefile of 0.11
  2. attempt to upgrade a statefile that is using the null provider from 0.11 to 0.12
  3. terraform plan
  4. fail

How much impact is this issue causing?

Low

Logs

No response

Additional Information

I know this can't be fixed with the new framework, but I would contend that the framework change should be consider a major change not a minor.

Code of Conduct

  • I agree to follow this project's Code of Conduct

[Terraform 0.12-rc1] Error: one of 'source_dir', 'source_file', 'source_content_filename' must be specified

Terraform Version

Terraform v0.12.0-rc1
+ provider.archive v1.2.2
+ provider.aws v2.11.0
+ provider.null v2.1.2
+ provider.random v2.1.2
+ provider.template v2.1.2
+ provider.tls v2.0.1

Affected Resource(s)

After upgrading my code to TF 0.12 and running a plan I get the following error:

Error: one of 'source_dir', 'source_file', 'source_content_filename' must be specified

  on modules/ui/data.tf line 21, in data "archive_file" "headers_lambda_code":
  21: data "archive_file" "headers_lambda_code" {

Terraform Configuration Files

My code defines a source_dir though:

data "archive_file" "headers_lambda_code" {
  type        = "zip"
  source_dir  = data.null_data_source.headers_zip_source.outputs.filename
  output_path = data.null_data_source.headers_zip_output.outputs.filename
}

The relevant null_data_sources:

data "null_data_source" "headers_zip_source" {
  inputs = {
    filename = substr(
      "${path.module}/headers_lambda_src",
      length(path.cwd) + 1,
      -1,
    )
  }
}

data "null_data_source" "headers_zip_output" {
  inputs = {
    filename = substr(
      "${path.module}/headers_lambda_zip/lambda_${var.component}.zip",
      length(path.cwd) + 1,
      -1,
    )
  }
}

When I look into the state file I realise that for some reason my null_data_sources are empty:

$ terraform0.12 state show module.ui.data.null_data_source.headers_zip_source
# module.ui.data.null_data_source.headers_zip_source:
data "null_data_source" "headers_zip_source" {
    has_computed_default = "default"
    id                   = "static"
    inputs               = {
        "filename" = ""
    }
    outputs              = {
        "filename" = ""
    }
    random               = "1245274724571935486"
}


$ terraform0.12 state show module.ui.data.null_data_source.headers_zip_output
# module.ui.data.null_data_source.headers_zip_output:
data "null_data_source" "headers_zip_output" {
    has_computed_default = "default"
    id                   = "static"
    inputs               = {
        "filename" = ""
    }
    outputs              = {
        "filename" = ""
    }
    random               = "4616215617319205940"
}

Expected Behavior

null_data_source should pick up the filename.

Actual Behavior

It failed as above.

Steps to Reproduce

terraform plan
terraform apply

Add acceptance tests

While the provider functionality is very basic, acceptance tests are still required in order to catch runtime issues.

null_resource.bootstrap: doesn't support update

This issue was originally opened by @bernadinm as hashicorp/terraform#13349. It was migrated here as part of the provider split. The original body of the issue is below.


Hi there,

Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html.

Terraform Version

Run terraform -v to show the version. If you are not running the latest version of Terraform, please upgrade because your issue may have already been fixed.

Terraform v0.9.2

Affected Resource(s)

  • null_resource

Terraform Configuration Files

resource "null_resource" "bootstrap" {
  # Changes to any instance of the cluster requires re-provisioning
  triggers {
    cluster_instance_ids = "${aws_instance.bootstrap.id}"
    dcos_version = "${var.dcos_version}"
    dcos_security = "${var.dcos_security}"
    num_of_masters = "${var.num_of_masters}"
  }

lifecycle {
    ignore_changes = ["data.template_file.cluster-name.rendered", "triggers.%", "triggers.dcos_security"]
  }
}

For example I removed dcos_security = "${var.dcos_security}" because I no longer want to track this but I get the error null_resource.bootstrap: doesn't support update

Expected Behavior

What should have happened?

Terraform should have made the change to the state but ignore deploying the change on the actually null_resource and all external dependencies like master and agent.

Actual Behavior

What actually happened?

It gave an error of null_resource.bootstrap: doesn't support update

Steps to Reproduce

  1. terraform apply

null_data_source marked deprecated

null_data_source is now reporting deprecated. Please remove the deprecated label as it is still required as a stopgap for miscellaneous deployment pipelines. The provisioner functionality is used extensively with this resource to allow numerous other resources to depend and wait for the provisioner to complete.

Terraform Version

Terraform v1.0.5
on linux_amd64
+ provider registry.terraform.io/brinkmanlab/galaxy v0.3.0
+ provider registry.terraform.io/hashicorp/external v2.1.0
+ provider registry.terraform.io/hashicorp/http v2.1.0
+ provider registry.terraform.io/hashicorp/local v2.1.0
+ provider registry.terraform.io/hashicorp/null v3.1.0
+ provider registry.terraform.io/hashicorp/random v3.1.0
+ provider registry.terraform.io/kreuzwerker/docker v2.13.0
+ provider registry.terraform.io/terraform-providers/docker v2.7.2

Affected Resource(s)

Please list the resources as a list, for example:

  • null_data_source

Terraform Configuration Files

# Copy-paste your Terraform configurations here - for large Terraform configs,
# please use a service like Dropbox and share a link to the ZIP file. For
# security, you can also encrypt the files using our GPG public key.

Debug Output

╷
│ Warning: Deprecated Resource
│ 
│   with module.galaxy.data.null_data_source.api_ready,
│   on .terraform/modules/galaxy/destinations/docker/main.tf line 10, in data "null_data_source" "api_ready":
│   10: data "null_data_source" "api_ready" {
│ 
│ The null_data_source was historically used to construct intermediate values to re-use elsewhere in configuration, the same can now be achieved using locals
│ 
│ (and one more similar warning elsewhere)
╵

Expected Behavior

Don't report depreciated

Actual Behavior

Reported depreciated

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply

References

https://stackoverflow.com/questions/62116684/how-to-make-terraform-wait-for-cloudinit-to-finish

Error: Provider produced invalid plan

Terraform CLI and Provider Versions

Terraform v0.13.6
-/null: version = "~> 3.2.1"

Terraform Configuration

data "external" "validate_subnets_script" {
  program = ["python", "${path.module}/scripts/validate_subnets.py"]
  query = {
    subnet_id = var.subnet_id
    region    = var.region
    role_arn  = var.role_arn
  }
}

  resource "null_resource" "validate_subnets" {
    triggers = data.external.validate_subnets_script.result["subnet_id"] == var.subnet_id ? {} : file("ERROR: Subnet should be private")
    lifecycle {
      ignore_changes = [
        triggers
      ]
    }
  }

Expected Behavior

This should have generated a normal plan and shown resources to change/update/delete/create.

Actual Behavior

Error: Provider produced invalid plan

Provider "registry.terraform.io/hashicorp/null" planned an invalid value for
module.ec2-instance-pp-vtsy32abopqhw.null_resource.validate_subnets.triggers:
planned value cty.NullVal(cty.Map(cty.String)) does not match config value
cty.MapValEmpty(cty.String).

This is a bug in the provider, which should be reported in the provider's own
issue tracker.

Steps to Reproduce

This issue doesn't occur when provider version is passed. works correctly with below configuration. However when the version is not passed it takes latest and shows error.
provider "null" {
version = "< 3.2.0"
}

How much impact is this issue causing?

High

Logs

No response

Additional Information

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Bump Development/Build Minimum Go Version to 1.17

Terraform CLI and Provider Versions

N/A (main branch development)

Use Cases or Problem Statement

Following the Go support policy and given the ecosystem availability and stability of the latest Go minor version, it's time to upgrade. This will ensure that this project can use recent improvements to the Go runtime, standard library functionality, and continue to receive security updates

Proposal

  • Run the following commands to upgrade the Go module files and remove deprecated syntax such as //+build:
go mod edit -go=1.17
go mod tidy
go fix
  • Ensure any GitHub Actions workflows (.github/workflows/*.yml) use 1.18 in place of any 1.17 and 1.17 in place of any 1.16 or earlier
  • Ensure the README or any Contributing documentation notes the Go 1.17 expected minimum
  • (Not applicable to all projects) Ensure the .go-version is at least 1.17 or later
  • Enable the tenv linter in .golangci.yml and remediate any issues.

How much impact is this issue causing?

Medium

Additional Information

Code of Conduct

  • I agree to follow this project's Code of Conduct

null_resource local exec bug with Azure Function App deployment

Terraform CLI and Provider Versions

Tested with following terraform versions.
0.12.0
0.15.0
1.1.4

Provider
azurerm = {
source = "hashicorp/azurerm"
version = "2.54.0"
}

Terraform Configuration

data "archive_file" "zip_functions" {
  type        = "zip"
  source_dir  = "C:/Users/../../subscription"
  output_path = "C:/Users/../../subscription.zip"
}

variable "resource_group" {
  type = string
}

variable "name" {
  type = string
}

resource "null_resource" "deploy_functions" {
  
  provisioner "local-exec" {
    command = <<-EOT
    az functionapp deployment source config-zip --src ${data.archive_file.zip_functions.output_path} --resource-group ${var.resource_group} --name ${var.name} --timeout 300
    EOT
  }
}

Expected Behavior

Before deploying the resource, I made sure I'm logged in and set the subscription with az login and az account set
When deploying this resource with the zip file, several things should happen:

  1. The code of the function app should be updated (in this case a new powershell function name)
  2. The modules of the function app should be updated (in this case a new powershell function)
  3. The function app should use the new modules when activated

This works completely fine when just using the az cli command without the terraform null_resource.

Actual Behavior

When deploying the null_resource the code of the function app is updated (1) and the modules are updated (2). However when running the function app, it doesn't recognize the new module names (3). It seems the function app doesn't refresh the modules that are imported when using the terraform null_resource.
A workaround is adding an import-module powershell command at the beginning of the run.ps1 file. This shouldn't be necessary however, because the normal behavior of the Function App is that this is always up to date.

Since this behavior is not seen when using the az-cli with the exact same command, it is probably related to the inner working of the terraform null_resource.

Steps to Reproduce

  1. terraform apply

How much impact is this issue causing?

Medium

Logs

No response

Additional Information

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Move docs directory structure to standard with /d/ and /r/

Terraform Version

N/A

Affected Resource(s)

data "null_data_source" and resource "null_resource"

Core issue

I've built a vscode extension (here on the marketplace) to pull code examples on each data source and resource from website/docs/r and website/docs/d of each public provider in this organization. This provider as well as http, external, and scaffolding all have documentation in the website/docs/ root which will make for ugly code on my end to accommodate these outliers. Is there a good reason these provider repos are structured differently? With a go ahead to move them to the standard directory structure, I'd be happy to own the PR for getting these final repos in line with the others.

Let me know if you see any issue with me shuffling the files around into directories. Thanks!

failing local exec still sets the id

resource "null_resource" "test" {
  provisioner "local-exec" {
    command = "/bin/fail"
  }
}

module "some" {
  source = "../somewhere"
  arg = "${null_resource.test.id}"
}

terraform apply will fail, but since the id is set, so the next apply will "run" the module, because the dependency to .id is there.

Enable go-changelog Automation

The "standard library" Terraform Providers should implement nascent provider development tooling to encourage consistency, foster automation where possible, and discover bugs/enhancements to that tooling. To that end, this provider's CHANGELOG handling should be switched to go-changelog, including:

  • Adding .changelog directory and template files
  • Enabling automation for regenerating the CHANGELOG (e.g. scripts or GitHub Actions)
  • (If enhancements are made available upstream in time) Enabling automation for checking CHANGELOG entries and formatting

Switch to GitHub Actions and goreleaser Release Process

The "standard library" Terraform Providers should implement nascent provider development tooling to encourage consistency, foster automation where possible, and discover bugs/enhancements to that tooling. To that end, this provider's release process should be switched to goreleaser to match the documented Terraform Registry publishing recommendations. This includes:

  • Creating necessary .goreleaser.yml and .github/workflows/release.yml configurations for tag-based releases (see also: TF-279 RFC)
  • Ensuring necessary GitHub or Vault tokens are in place to fetch release secrets
  • Ensuring provider and internal release process documentation is updated

Unable to use output variable as list

This issue was originally opened by @nusnewob as hashicorp/terraform#8048. It was migrated here as part of the provider split. The original body of the issue is below.


Terraform Version

Terraform v0.7.0

Affected Resource(s)

  • aws_elb
  • aws_db_subnet_group

Terraform Configuration Files

main.tf

module "subnets" {
  source = "./modules/test"
}

resource "aws_elb" "elb" {
  name = "test"
  subnets = ["${module.subnets.subnets["public"]}"]
  listener {
    lb_port = 80
    lb_protocol = "http"
    instance_port = 80
    instance_protocol = "http"
  }
}

or

...
  subnets = ["${split(",", join(",", module.subnets.subnets["public"]))}"]
...

modules/test/module.tf

data "null_data_source" "subnets" {
  inputs = {
    public = ["subnet-abcd1234","subnet-abcd1235","subnet-abcd1236"]
  }
}

output "subnets" {
  value = "${data.null_data_source.subnets.input}"
}

Debug Output

https://gist.github.com/nusnewob/b3230d0d83c40917516a068b3532092f

Expected Behavior

Should be able to pass the module output as list variable

Actual Behavior

Error refreshing state: 1 error(s) occurred:

* inputs: 1 error(s) decoding:

* '[public]' expected type 'string', got unconvertible type '[]interface {}'

Steps to Reproduce

  1. terraform apply or terraform plan

null_resource triggers unneccessary replace

Terraform CLI and Provider Versions

❯ terraform version
Terraform v1.3.2
on linux_amd64
+ provider registry.terraform.io/hashicorp/archive v2.2.0
+ provider registry.terraform.io/hashicorp/null v3.2.0

Terraform Configuration

resource "null_resource" "create_zip_every_time" {
  triggers = {
    always_run = timestamp()
  }
}

data "archive_file" "bundle" {
  type = "zip"

  output_path = "/tmp/foo.zip"
  depends_on  = [null_resource.create_zip_every_time]

  source {
    filename = "foo.txt"
    content  = "foo"
  }
}

resource "null_resource" "dependent" {
  triggers = {
    checksum = data.archive_file.bundle.output_md5
  }
}

output "checksum" {
  value = data.archive_file.bundle.output_md5
}

Expected Behavior

I know the config is a bit weird but I'm just trying to show a minimal reproduce.
As you can see in the config, eventhough archive_file is forced to be created each time, the checksum never actually changes as it's the same content over and over. But with this config, the null_resource.dependent resource keeps getting deleted and recreated unnecessarily while I expected it should be a no-op since the value of the checksum is exactly the same at the end.

Actual Behavior

The null_resource.dependent keeps getting deleted and created again

Terraform used the selected providers to generate the following execution plan. Resource actions are
indicated with the following symbols:
-/+ destroy and then create replacement
 <= read (data resources)

Terraform will perform the following actions:

  # data.archive_file.bundle will be read during apply
  # (depends on a resource or a module with changes pending)
 <= data "archive_file" "bundle" {
      + id                  = (known after apply)
      + output_base64sha256 = (known after apply)
      + output_md5          = (known after apply)
      + output_path         = "/tmp/foo.zip"
      + output_sha          = (known after apply)
      + output_size         = (known after apply)
      + type                = "zip"

      + source {
          + content  = "foo"
          + filename = "foo.txt"
        }
    }

  # null_resource.create_zip_every_time must be replaced
-/+ resource "null_resource" "create_zip_every_time" {
      ~ id       = "5577006791947779410" -> (known after apply)
      ~ triggers = { # forces replacement
          ~ "always_run" = "2022-11-17T21:46:19Z" -> (known after apply)
        }
    }

  # null_resource.dependent must be replaced
-/+ resource "null_resource" "dependent" {
      ~ id       = "8674665223082153551" -> (known after apply)
      ~ triggers = { # forces replacement
          ~ "checksum" = "65681cd4d9d55e9eb423edba41dca393" -> (known after apply)
        }
    }

Plan: 2 to add, 0 to change, 2 to destroy.

Changes to Outputs:
  ~ checksum = "65681cd4d9d55e9eb423edba41dca393" -> (known after apply)

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

null_resource.dependent: Destroying... [id=8674665223082153551]
null_resource.dependent: Destruction complete after 0s
null_resource.create_zip_every_time: Destroying... [id=5577006791947779410]
null_resource.create_zip_every_time: Destruction complete after 0s
null_resource.create_zip_every_time: Creating...
null_resource.create_zip_every_time: Creation complete after 0s [id=5577006791947779410]
data.archive_file.bundle: Reading...
data.archive_file.bundle: Read complete after 0s [id=6af8b2a5aa15493d28dc45d2009e35b1d8238294]
null_resource.dependent: Creating...
null_resource.dependent: Creation complete after 0s [id=8674665223082153551]

Apply complete! Resources: 2 added, 0 changed, 2 destroyed.

Outputs:

checksum = "65681cd4d9d55e9eb423edba41dca393"

Steps to Reproduce

terraform apply

How much impact is this issue causing?

Medium

Logs

https://gist.github.com/AmineChikhaoui/c656044fcbd04c1516164c8fc271af59

Additional Information

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.