From e3fab9aaa095c21d19845a7be6025ef912f576ad Mon Sep 17 00:00:00 2001 From: Selena Goods Date: Thu, 28 Mar 2024 15:45:23 -0400 Subject: [PATCH] Strip Provider Prefix from File Names during Migration (#349) * Add `--provider-name` flag to `migrate` subcommand and strip provider short name prefix during migration * Update README.md * Add changelog entries * Default the `--provider-name` flag to use the provider directory basename * Update .changes/unreleased/ENHANCEMENTS-20240327-160831.yaml Co-authored-by: Brian Flad --------- Co-authored-by: Brian Flad --- .../unreleased/BUG FIXES-20240327-161037.yaml | 6 + .../ENHANCEMENTS-20240327-160831.yaml | 6 + README.md | 28 +- ...der_success_docs_website_with_prefix.txtar | 964 +++++++++++++++++ ...r_success_legacy_website_with_prefix.txtar | 968 ++++++++++++++++++ internal/cmd/migrate.go | 4 + internal/provider/migrate.go | 18 +- 7 files changed, 1980 insertions(+), 14 deletions(-) create mode 100644 .changes/unreleased/BUG FIXES-20240327-161037.yaml create mode 100644 .changes/unreleased/ENHANCEMENTS-20240327-160831.yaml create mode 100644 cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website_with_prefix.txtar create mode 100644 cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website_with_prefix.txtar diff --git a/.changes/unreleased/BUG FIXES-20240327-161037.yaml b/.changes/unreleased/BUG FIXES-20240327-161037.yaml new file mode 100644 index 00000000..b1f57600 --- /dev/null +++ b/.changes/unreleased/BUG FIXES-20240327-161037.yaml @@ -0,0 +1,6 @@ +kind: BUG FIXES +body: 'migrate: fixed a bug where documentation files with provider name prefixes were + migrated to templates directory as-is, causing `generate` to create duplicate templates' +time: 2024-03-27T16:10:37.029568-04:00 +custom: + Issue: "349" diff --git a/.changes/unreleased/ENHANCEMENTS-20240327-160831.yaml b/.changes/unreleased/ENHANCEMENTS-20240327-160831.yaml new file mode 100644 index 00000000..d71c550b --- /dev/null +++ b/.changes/unreleased/ENHANCEMENTS-20240327-160831.yaml @@ -0,0 +1,6 @@ +kind: ENHANCEMENTS +body: 'migrate: Added `--provider-name` flag to override the default provider name when any + file names that contain provider name prefixes are removed during migration' +time: 2024-03-27T16:08:31.541882-04:00 +custom: + Issue: "349" diff --git a/README.md b/README.md index fc2f3895..be44fe32 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ Usage: tfplugindocs migrate [] --examples-dir examples directory based on provider-dir (default: "examples") --provider-dir relative or absolute path to the root provider code directory when running the command outside the root provider code directory --templates-dir new website templates directory based on provider-dir; files will be migrated to this directory (default: "templates") + --provider-name provider name, as used in Terraform configurations; this will default to provider-dir basename if not set ``` ### How it Works @@ -175,23 +176,24 @@ ingress issues. The `migrate` subcommand takes the following actions: 1. Determines the rendered website directory based on the `--provider-dir` argument -2. Copies the contents of the rendered website directory to the `--templates-dir` folder (will create this folder if it doesn't exist) -3. (if the rendered website is using legacy format) Renames `docs/d/` and `docs/r/` subdirectories to `data-sources/` and `resources/` respectively -4. Change file suffixes for Markdown files to `.md.tmpl` to create website templates -5. Extracts code blocks from website docs to create individual example files in `--examples-dir` (will create this folder if it doesn't exist) -6. Replace extracted example code in website templates with `codefile`/`tffile` template functions referencing the example files. -7. Copies non-template files to `--templates-dir` folder -8. Removes the `website/` directory +2. Determines the provider name based on the `--provider-name` argument +3. Copies the contents of the rendered website directory to the `--templates-dir` folder (will create this folder if it doesn't exist) +4. (if the rendered website is using legacy format) Renames `docs/d/` and `docs/r/` subdirectories to `data-sources/` and `resources/` respectively +5. Renames files in the `--templates-dir` folder to remove the provider shortname prefix from the file name +6. Change file suffixes for Markdown files to `.md.tmpl` to create website templates +7. Extracts code blocks from website docs to create individual example files in `--examples-dir` (will create this folder if it doesn't exist) +8. Replace extracted example code in website templates with `codefile`/`tffile` template functions referencing the example files. +9. Copies non-template files to `--templates-dir` folder +10. Removes the `website/` directory ### Conventional Paths The generation of missing documentation is based on a number of assumptions / conventional paths. -> **NOTE:** In the following conventional paths, `` and `` include the provider prefix as well, but the provider prefix is **NOT** included in``. -> For example, the data source [`caller_identity`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) in the `aws` provider would have an "example" conventional path of: `examples/data-sources/aws_caller_identity/data-source.tf` - For templates: +> **NOTE:** In the following conventional paths for templates, ``, ``, and `` do not include the provider prefix. + | Path | Description | |-------------------------------------------------------|----------------------------------------| | `templates/` | Root of templated docs | @@ -207,6 +209,9 @@ Note: the `.tmpl` extension is necessary, for the file to be correctly handled a For examples: +> **NOTE:** In the following conventional paths for examples, `` and `` include the provider prefix as well, but the provider prefix is **NOT** included in``. +> For example, the data source [`caller_identity`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) in the `aws` provider would have an "example" conventional path of: `examples/data-sources/aws_caller_identity/data-source.tf` + | Path | Description | |-----------------------------------------------------------|---------------------------------| | `examples/` | Root of examples | @@ -220,6 +225,9 @@ For examples: The `migrate` subcommand assumes the following conventional paths for the rendered website directory: +> **NOTE:** In the following conventional paths for templates, ``, ``, and `` do not include the provider prefix. +> if the `--provider-name` argument is set, the provider prefix will be removed from the file names during migration. + Legacy website directory structure: | Path | Description | diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website_with_prefix.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website_with_prefix.txtar new file mode 100644 index 00000000..0192624b --- /dev/null +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website_with_prefix.txtar @@ -0,0 +1,964 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# Successful run of tfplugindocs -migrate on the Time provider using the docs website layout with provider name prefix +[!unix] skip + +# Run migrate command +exec tfplugindocs migrate --provider-name=terraform-provider-time +cmpenv stdout expected-output.txt + +# Check template files +cmpenv templates/index.md.tmpl exp-templates/index.md.tmpl +cmpenv templates/functions/rfc3339_parse.md.tmpl exp-templates/functions/rfc3339_parse.md.tmpl +cmpenv templates/resources/offset.md.tmpl exp-templates/resources/offset.md.tmpl +cmpenv templates/resources/rotating.md.tmpl exp-templates/resources/rotating.md.tmpl +cmpenv templates/resources/sleep.md.tmpl exp-templates/resources/sleep.md.tmpl +cmpenv templates/resources/static.md.tmpl exp-templates/resources/static.md.tmpl + +# Check generated example files +cmpenv examples/example_1.tf examples/example_1.tf + +cmpenv examples/functions/rfc3339_parse/example_1.tf exp-examples/functions/rfc3339_parse/example_1.tf + +cmpenv examples/resources/offset/example_1.tf exp-examples/resources/offset/example_1.tf +cmpenv examples/resources/offset/example_2.tf exp-examples/resources/offset/example_2.tf +cmpenv examples/resources/offset/import_1.sh exp-examples/resources/offset/import_1.sh + +cmpenv examples/resources/rotating/example_1.tf exp-examples/resources/rotating/example_1.tf +cmpenv examples/resources/rotating/import_1.sh exp-examples/resources/rotating/import_1.sh +cmpenv examples/resources/rotating/import_2.sh exp-examples/resources/rotating/import_2.sh + +cmpenv examples/resources/sleep/example_1.tf exp-examples/resources/sleep/example_1.tf +cmpenv examples/resources/sleep/example_2.tf exp-examples/resources/sleep/example_2.tf +cmpenv examples/resources/sleep/example_3.tf exp-examples/resources/sleep/example_3.tf +cmpenv examples/resources/sleep/import_1.sh exp-examples/resources/sleep/import_1.sh +cmpenv examples/resources/sleep/import_2.sh exp-examples/resources/sleep/import_2.sh + +cmpenv examples/resources/static/example_1.tf examples/resources/static/example_1.tf +cmpenv examples/resources/static/example_2.tf examples/resources/static/example_2.tf +cmpenv examples/resources/static/import_1.sh examples/resources/static/import_1.sh + +-- expected-output.txt -- +migrating website from "$WORK/docs" to "$WORK/templates" +migrating functons directory: functions +migrating file "time_rfc3339_parse.html.markdown" +extracting YAML frontmatter to "$WORK/templates/functions/rfc3339_parse.md.tmpl" +extracting code examples from "time_rfc3339_parse.html.markdown" +creating example file "$WORK/examples/functions/rfc3339_parse/example_1.tf" +skipping code block with unknown language "text" +finished creating template "$WORK/templates/functions/rfc3339_parse.md.tmpl" +migrating provider index: index.html.markdown +migrating file "index.html.markdown" +extracting YAML frontmatter to "$WORK/templates/index.md.tmpl" +extracting code examples from "index.html.markdown" +creating example file "$WORK/examples/example_1.tf" +finished creating template "$WORK/templates/index.md.tmpl" +migrating resources directory: resources +migrating file "time_offset.html.markdown" +extracting YAML frontmatter to "$WORK/templates/resources/offset.md.tmpl" +extracting code examples from "time_offset.html.markdown" +creating example file "$WORK/examples/resources/offset/example_1.tf" +creating example file "$WORK/examples/resources/offset/example_2.tf" +creating import file "$WORK/examples/resources/offset/import_1.sh" +finished creating template "$WORK/templates/resources/offset.md.tmpl" +migrating file "time_rotating.html.markdown" +extracting YAML frontmatter to "$WORK/templates/resources/rotating.md.tmpl" +extracting code examples from "time_rotating.html.markdown" +creating example file "$WORK/examples/resources/rotating/example_1.tf" +creating import file "$WORK/examples/resources/rotating/import_1.sh" +creating import file "$WORK/examples/resources/rotating/import_2.sh" +finished creating template "$WORK/templates/resources/rotating.md.tmpl" +migrating file "time_sleep.html.markdown" +extracting YAML frontmatter to "$WORK/templates/resources/sleep.md.tmpl" +extracting code examples from "time_sleep.html.markdown" +creating example file "$WORK/examples/resources/sleep/example_1.tf" +creating example file "$WORK/examples/resources/sleep/example_2.tf" +creating example file "$WORK/examples/resources/sleep/example_3.tf" +creating import file "$WORK/examples/resources/sleep/import_1.sh" +creating import file "$WORK/examples/resources/sleep/import_2.sh" +finished creating template "$WORK/templates/resources/sleep.md.tmpl" +migrating file "time_static.html.markdown" +extracting YAML frontmatter to "$WORK/templates/resources/static.md.tmpl" +extracting code examples from "time_static.html.markdown" +creating example file "$WORK/examples/resources/static/example_1.tf" +creating example file "$WORK/examples/resources/static/example_2.tf" +creating import file "$WORK/examples/resources/static/import_1.sh" +finished creating template "$WORK/templates/resources/static.md.tmpl" +-- docs/index.html.markdown -- +--- +layout: "time" +page_title: "Provider: Time" +description: |- + The time provider is used to interact with time-based resources. +--- + +# Time Provider + +The time provider is used to interact with time-based resources. The provider itself has no configuration options. + +Use the navigation to the left to read about the available resources. + +## Resource "Triggers" + +Certain time resources, only perform actions during specific lifecycle actions: + +- `time_offset`: Saves base timestamp into Terraform state only when created. +- `time_sleep`: Sleeps when created and/or destroyed. +- `time_static`: Saves base timestamp into Terraform state only when created. + +These resources provide an optional map argument called `triggers` that can be populated with arbitrary key/value pairs. When the keys or values of this argument are updated, Terraform will re-perform the desired action, such as updating the base timestamp or sleeping again. + +For example: + +```hcl +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +`triggers` are *not* treated as sensitive attributes; a value used for `triggers` will be displayed in Terraform UI output as plaintext. + +To force a these actions to reoccur without updating `triggers`, the [`terraform taint` command](https://www.terraform.io/docs/commands/taint.html) can be used to produce the action on the next run. +-- docs/functions/time_rfc3339_parse.html.markdown -- +--- +page_title: "rfc3339_parse Function - Time" +subcategory: "" +description: |- + Parse an RFC3339 timestamp string +--- + +# rfc3339_parse Function + +Given an RFC3339 timestamp string, will parse and return an object representation of that date and time. + +## Example Usage + +```terraform +output "test" { + value = provider::time::rfc3339_parse("2023-07-25T23:43:16-00:00") +} +``` + +## Signature + +```text +rfc3339_parse(timestamp string) Object +``` + +## Arguments + +1. `timestamp` (string) RFC3339 timestamp string to parse +-- docs/resources/time_offset.html.markdown -- +--- +layout: "time" +page_title: "Time: time_offset" +description: |- + Manages a offset time resource. +--- + +# Resource: time_offset + +Manages an offset time resource, which keeps an UTC timestamp stored in the Terraform state that is offset from a locally sourced base timestamp. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +```hcl +resource "time_offset" "example" { + offset_days = 7 +} + +output "one_week_from_now" { + value = time_offset.example.rfc3339 +} +``` + +### Triggers Usage + +```hcl +resource "time_offset" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } + + offset_days = 7 +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_offset resource to ensure that + # both will change together. + ami = time_offset.ami_update.triggers.ami_id + + tags = { + ExpirationTime = time_offset.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +## Argument Reference + +~> **NOTE:** At least one of the `offset_` arguments must be configured. + +The following arguments are optional: + +* `base_rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `offset_days` - (Optional) Number of days to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_hours` - (Optional) Number of hours to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_minutes` - (Optional) Number of minutes to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_months` - (Optional) Number of months to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_seconds` - (Optional) Number of seconds to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_years` - (Optional) Number of years to offset the base timestamp. Conflicts with other `offset_` arguments. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of offset timestamp. +* `hour` - Number hour of offset timestamp. +* `id` - UTC RFC3339 format of the base timestamp, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of offset timestamp. +* `month` - Number month of offset timestamp. +* `rfc3339` - UTC RFC3339 format of the offset timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of offset timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of offset timestamp. + +## Import + +This resource can be imported using the base UTC RFC3339 timestamp and offset years, months, days, hours, minutes, and seconds, separated by commas (`,`), e.g. + +```console +$ terraform import time_offset.example 2020-02-12T06:36:13Z,0,0,7,0,0,0 +``` + +The `triggers` argument cannot be imported. +-- docs/resources/time_rotating.html.markdown -- +--- +layout: "time" +page_title: "Time: time_rotating" +description: |- + Manages a rotating time resource. +--- + +# Resource: time_rotating + +Manages a rotating time resource, which keeps a rotating UTC timestamp stored in the Terraform state and proposes resource recreation when the locally sourced current time is beyond the rotation time. This rotation only occurs when Terraform is executed, meaning there will be drift between the rotation timestamp and actual rotation. The new rotation timestamp offset includes this drift. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html) by only forcing a new value on the set cadence. + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +This example configuration will rotate (destroy/create) the resource every 30 days. + +```hcl +resource "time_rotating" "example" { + rotation_days = 30 +} +``` + +## Argument Reference + +~> **NOTE:** At least one of the `rotation_` arguments must be configured. + +The following arguments are optional: + +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. +* `rotation_days` - (Optional) Number of days to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_hours` - (Optional) Number of hours to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_minutes` - (Optional) Number of minutes to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_months` - (Optional) Number of months to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_rfc3339` - (Optional) Configure the rotation timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_years` - (Optional) Number of years to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. These conditions recreate the resource in addition to other rotation arguments. See [the main provider documentation](../index.html) for more information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 format of the base timestamp, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the base UTC RFC3339 value and rotation years, months, days, hours, and minutes, separated by commas (`,`), e.g. for 30 days + +```console +$ terraform import time_rotation.example 2020-02-12T06:36:13Z,0,0,30,0,0 +``` + +Otherwise, to import with the rotation RFC3339 value, the base UTC RFC3339 value and rotation UTC RFC3339 value, separated by commas (`,`), e.g. + +```console +$ terraform import time_rotation.example 2020-02-12T06:36:13Z,2020-02-13T06:36:13Z +``` + +The `triggers` argument cannot be imported. +-- docs/resources/time_sleep.html.markdown -- +--- +layout: "time" +page_title: "Time: time_sleep" +description: |- + Manages a static time resource. +--- + +# Resource: time_sleep + +Manages a resource that delays creation and/or destruction, typically for further resources. This prevents cross-platform compatibility and destroy-time issues with using the [`local-exec` provisioner](https://www.terraform.io/docs/provisioners/local-exec.html). + +-> In many cases, this resource should be considered a workaround for issues that should be reported and handled in downstream Terraform Provider logic. Downstream resources can usually introduce or adjust retries in their code to handle time delay issues for all Terraform configurations or upstream resources can be improved to better wait for a resource to be fully ready and available. + +## Example Usage + +### Delay Create Usage + +```hcl +# This resource will destroy (potentially immediately) after null_resource.next +resource "null_resource" "previous" {} + +resource "time_sleep" "wait_30_seconds" { + depends_on = [null_resource.previous] + + create_duration = "30s" +} + +# This resource will create (at least) 30 seconds after null_resource.previous +resource "null_resource" "next" { + depends_on = [time_sleep.wait_30_seconds] +} +``` + +### Delay Destroy Usage + +```hcl +# This resource will destroy (at least) 30 seconds after null_resource.next +resource "null_resource" "previous" {} + +resource "time_sleep" "wait_30_seconds" { + depends_on = [null_resource.previous] + + destroy_duration = "30s" +} + +# This resource will create (potentially immediately) after null_resource.previous +resource "null_resource" "next" { + depends_on = [time_sleep.wait_30_seconds] +} +``` + +### Triggers Usage + +```hcl +resource "aws_ram_resource_association" "example" { + resource_arn = aws_subnet.example.arn + resource_share_arn = aws_ram_resource_share.example.arn +} + +# AWS resources shared via Resource Access Manager can take a few seconds to +# propagate across AWS accounts after RAM returns a successful association. +resource "time_sleep" "ram_resource_propagation" { + create_duration = "60s" + + triggers = { + # This sets up a proper dependency on the RAM association + subnet_arn = aws_ram_resource_association.example.resource_arn + subnet_id = aws_subnet.example.id + } +} + +resource "aws_db_subnet_group" "example" { + name = "example" + + # Read the Subnet identifier "through" the time_sleep resource to ensure a + # proper dependency and that both will change together. + subnet_ids = [time_sleep.ram_resource_propagation.triggers["subnet_id"]] +} +``` + +## Argument Reference + +The following arguments are optional: + +* `create_duration` - (Optional) [Time duration][1] to delay resource creation. For example, `30s` for 30 seconds or `5m` for 5 minutes. Updating this value by itself will not trigger a delay. +* `destroy_duration` - (Optional) [Time duration][1] to delay resource destroy. For example, `30s` for 30 seconds or `5m` for 5 minutes. Updating this value by itself will not trigger a delay. This value or any updates to it must be successfully applied into the Terraform state before destroying this resource to take effect. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will run any creation or destroy delays again. See [the main provider documentation](../index.html) for more information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - UTC RFC3339 timestamp of the creation or import, e.g. `2020-02-12T06:36:13Z`. + +## Import + +This resource can be imported with the `create_duration` and `destroy_duration`, separated by a comma (`,`). + +e.g. For 30 seconds create duration with no destroy duration: + +```console +$ terraform import time_sleep.example 30s, +``` + +e.g. For 30 seconds destroy duration with no create duration: + +```console +$ terraform import time_sleep.example ,30s +``` + +The `triggers` argument cannot be imported. + +[1]: https://golang.org/pkg/time/#ParseDuration +-- docs/resources/time_static.html.markdown -- +--- +layout: "time" +page_title: "Time: time_static" +description: |- + Manages a static time resource. +--- + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +```hcl +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +``` + +### Triggers Usage + +```hcl +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +```console +$ terraform import time_static.example 2020-02-12T06:36:13Z +``` + +The `triggers` argument cannot be imported. +-- exp-examples/example_1.tf -- +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/functions/rfc3339_parse/example_1.tf -- +output "test" { + value = provider::time::rfc3339_parse("2023-07-25T23:43:16-00:00") +} +-- exp-examples/resources/offset/example_1.tf -- +resource "time_offset" "example" { + offset_days = 7 +} + +output "one_week_from_now" { + value = time_offset.example.rfc3339 +} +-- exp-examples/resources/offset/example_2.tf -- +resource "time_offset" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } + + offset_days = 7 +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_offset resource to ensure that + # both will change together. + ami = time_offset.ami_update.triggers.ami_id + + tags = { + ExpirationTime = time_offset.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/resources/offset/import_1.sh -- +$ terraform import time_offset.example 2020-02-12T06:36:13Z,0,0,7,0,0,0 +-- exp-examples/resources/rotating/example_1.tf -- +resource "time_rotating" "example" { + rotation_days = 30 +} +-- exp-examples/resources/rotating/import_1.sh -- +$ terraform import time_rotation.example 2020-02-12T06:36:13Z,0,0,30,0,0 +-- exp-examples/resources/rotating/import_2.sh -- +$ terraform import time_rotation.example 2020-02-12T06:36:13Z,2020-02-13T06:36:13Z +-- exp-examples/resources/sleep/example_1.tf -- +# This resource will destroy (potentially immediately) after null_resource.next +resource "null_resource" "previous" {} + +resource "time_sleep" "wait_30_seconds" { + depends_on = [null_resource.previous] + + create_duration = "30s" +} + +# This resource will create (at least) 30 seconds after null_resource.previous +resource "null_resource" "next" { + depends_on = [time_sleep.wait_30_seconds] +} +-- exp-examples/resources/sleep/example_2.tf -- +# This resource will destroy (at least) 30 seconds after null_resource.next +resource "null_resource" "previous" {} + +resource "time_sleep" "wait_30_seconds" { + depends_on = [null_resource.previous] + + destroy_duration = "30s" +} + +# This resource will create (potentially immediately) after null_resource.previous +resource "null_resource" "next" { + depends_on = [time_sleep.wait_30_seconds] +} +-- exp-examples/resources/sleep/example_3.tf -- +resource "aws_ram_resource_association" "example" { + resource_arn = aws_subnet.example.arn + resource_share_arn = aws_ram_resource_share.example.arn +} + +# AWS resources shared via Resource Access Manager can take a few seconds to +# propagate across AWS accounts after RAM returns a successful association. +resource "time_sleep" "ram_resource_propagation" { + create_duration = "60s" + + triggers = { + # This sets up a proper dependency on the RAM association + subnet_arn = aws_ram_resource_association.example.resource_arn + subnet_id = aws_subnet.example.id + } +} + +resource "aws_db_subnet_group" "example" { + name = "example" + + # Read the Subnet identifier "through" the time_sleep resource to ensure a + # proper dependency and that both will change together. + subnet_ids = [time_sleep.ram_resource_propagation.triggers["subnet_id"]] +} +-- exp-examples/resources/sleep/import_1.sh -- +$ terraform import time_sleep.example 30s, +-- exp-examples/resources/sleep/import_2.sh -- +$ terraform import time_sleep.example ,30s +-- exp-examples/resources/static/example_1.tf -- +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +-- exp-examples/resources/static/example_2.tf -- +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/resources/static/import_1.sh -- +$ terraform import time_static.example 2020-02-12T06:36:13Z +-- exp-templates/index.md.tmpl -- +--- +page_title: "Provider: Time" +description: |- + The time provider is used to interact with time-based resources. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# Time Provider + +The time provider is used to interact with time-based resources. The provider itself has no configuration options. + +Use the navigation to the left to read about the available resources. + +## Resource "Triggers" + +Certain time resources, only perform actions during specific lifecycle actions: + +- `time_offset`: Saves base timestamp into Terraform state only when created. +- `time_sleep`: Sleeps when created and/or destroyed. +- `time_static`: Saves base timestamp into Terraform state only when created. + +These resources provide an optional map argument called `triggers` that can be populated with arbitrary key/value pairs. When the keys or values of this argument are updated, Terraform will re-perform the desired action, such as updating the base timestamp or sleeping again. + +For example: + +{{tffile "examples/example_1.tf"}} + +`triggers` are *not* treated as sensitive attributes; a value used for `triggers` will be displayed in Terraform UI output as plaintext. + +To force a these actions to reoccur without updating `triggers`, the [`terraform taint` command](https://www.terraform.io/docs/commands/taint.html) can be used to produce the action on the next run. +-- exp-templates/functions/rfc3339_parse.md.tmpl -- +--- +page_title: "rfc3339_parse Function - Time" +subcategory: "" +description: |- + Parse an RFC3339 timestamp string +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .FunctionArgumentsMarkdown }} template can be used to replace manual argument documentation if descriptions of function arguments are added in the provider source code. */ -}} + +# rfc3339_parse Function + +Given an RFC3339 timestamp string, will parse and return an object representation of that date and time. + +## Example Usage + +{{tffile "examples/functions/rfc3339_parse/example_1.tf"}} + +## Signature + +```text +rfc3339_parse(timestamp string) Object +``` + +## Arguments + +1. `timestamp` (string) RFC3339 timestamp string to parse +-- exp-templates/resources/offset.md.tmpl -- +--- +page_title: "Time: time_offset" +description: |- + Manages a offset time resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# Resource: time_offset + +Manages an offset time resource, which keeps an UTC timestamp stored in the Terraform state that is offset from a locally sourced base timestamp. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +{{tffile "examples/resources/offset/example_1.tf"}} + +### Triggers Usage + +{{tffile "examples/resources/offset/example_2.tf"}} + +## Argument Reference + +~> **NOTE:** At least one of the `offset_` arguments must be configured. + +The following arguments are optional: + +* `base_rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `offset_days` - (Optional) Number of days to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_hours` - (Optional) Number of hours to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_minutes` - (Optional) Number of minutes to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_months` - (Optional) Number of months to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_seconds` - (Optional) Number of seconds to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_years` - (Optional) Number of years to offset the base timestamp. Conflicts with other `offset_` arguments. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of offset timestamp. +* `hour` - Number hour of offset timestamp. +* `id` - UTC RFC3339 format of the base timestamp, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of offset timestamp. +* `month` - Number month of offset timestamp. +* `rfc3339` - UTC RFC3339 format of the offset timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of offset timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of offset timestamp. + +## Import + +This resource can be imported using the base UTC RFC3339 timestamp and offset years, months, days, hours, minutes, and seconds, separated by commas (`,`), e.g. + +{{codefile "shell" "examples/resources/offset/import_1.sh"}} + +The `triggers` argument cannot be imported. +-- exp-templates/resources/rotating.md.tmpl -- +--- +page_title: "Time: time_rotating" +description: |- + Manages a rotating time resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# Resource: time_rotating + +Manages a rotating time resource, which keeps a rotating UTC timestamp stored in the Terraform state and proposes resource recreation when the locally sourced current time is beyond the rotation time. This rotation only occurs when Terraform is executed, meaning there will be drift between the rotation timestamp and actual rotation. The new rotation timestamp offset includes this drift. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html) by only forcing a new value on the set cadence. + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +This example configuration will rotate (destroy/create) the resource every 30 days. + +{{tffile "examples/resources/rotating/example_1.tf"}} + +## Argument Reference + +~> **NOTE:** At least one of the `rotation_` arguments must be configured. + +The following arguments are optional: + +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. +* `rotation_days` - (Optional) Number of days to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_hours` - (Optional) Number of hours to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_minutes` - (Optional) Number of minutes to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_months` - (Optional) Number of months to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_rfc3339` - (Optional) Configure the rotation timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_years` - (Optional) Number of years to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. These conditions recreate the resource in addition to other rotation arguments. See [the main provider documentation](../index.html) for more information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 format of the base timestamp, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the base UTC RFC3339 value and rotation years, months, days, hours, and minutes, separated by commas (`,`), e.g. for 30 days + +{{codefile "shell" "examples/resources/rotating/import_1.sh"}} + +Otherwise, to import with the rotation RFC3339 value, the base UTC RFC3339 value and rotation UTC RFC3339 value, separated by commas (`,`), e.g. + +{{codefile "shell" "examples/resources/rotating/import_2.sh"}} + +The `triggers` argument cannot be imported. +-- exp-templates/resources/sleep.md.tmpl -- +--- +page_title: "Time: time_sleep" +description: |- + Manages a static time resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# Resource: time_sleep + +Manages a resource that delays creation and/or destruction, typically for further resources. This prevents cross-platform compatibility and destroy-time issues with using the [`local-exec` provisioner](https://www.terraform.io/docs/provisioners/local-exec.html). + +-> In many cases, this resource should be considered a workaround for issues that should be reported and handled in downstream Terraform Provider logic. Downstream resources can usually introduce or adjust retries in their code to handle time delay issues for all Terraform configurations or upstream resources can be improved to better wait for a resource to be fully ready and available. + +## Example Usage + +### Delay Create Usage + +{{tffile "examples/resources/sleep/example_1.tf"}} + +### Delay Destroy Usage + +{{tffile "examples/resources/sleep/example_2.tf"}} + +### Triggers Usage + +{{tffile "examples/resources/sleep/example_3.tf"}} + +## Argument Reference + +The following arguments are optional: + +* `create_duration` - (Optional) [Time duration](https://golang.org/pkg/time/#ParseDuration) to delay resource creation. For example, `30s` for 30 seconds or `5m` for 5 minutes. Updating this value by itself will not trigger a delay. +* `destroy_duration` - (Optional) [Time duration](https://golang.org/pkg/time/#ParseDuration) to delay resource destroy. For example, `30s` for 30 seconds or `5m` for 5 minutes. Updating this value by itself will not trigger a delay. This value or any updates to it must be successfully applied into the Terraform state before destroying this resource to take effect. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will run any creation or destroy delays again. See [the main provider documentation](../index.html) for more information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - UTC RFC3339 timestamp of the creation or import, e.g. `2020-02-12T06:36:13Z`. + +## Import + +This resource can be imported with the `create_duration` and `destroy_duration`, separated by a comma (`,`). + +e.g. For 30 seconds create duration with no destroy duration: + +{{codefile "shell" "examples/resources/sleep/import_1.sh"}} + +e.g. For 30 seconds destroy duration with no create duration: + +{{codefile "shell" "examples/resources/sleep/import_2.sh"}} + +The `triggers` argument cannot be imported. +-- exp-templates/resources/static.md.tmpl -- +--- +page_title: "Time: time_static" +description: |- + Manages a static time resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +{{tffile "examples/resources/static/example_1.tf"}} + +### Triggers Usage + +{{tffile "examples/resources/static/example_2.tf"}} + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +{{codefile "shell" "examples/resources/static/import_1.sh"}} + +The `triggers` argument cannot be imported. \ No newline at end of file diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website_with_prefix.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website_with_prefix.txtar new file mode 100644 index 00000000..75f93373 --- /dev/null +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website_with_prefix.txtar @@ -0,0 +1,968 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# Successful run of tfplugindocs -migrate on the Time provider using the legacy website layout with provider shortname prefix +[!unix] skip + +# Run migrate command +exec tfplugindocs migrate --provider-name=terraform-provider-time +cmpenv stdout expected-output.txt + +# Check template files +cmpenv templates/index.md.tmpl exp-templates/index.md.tmpl +cmpenv templates/functions/rfc3339_parse.md.tmpl exp-templates/functions/rfc3339_parse.md.tmpl +cmpenv templates/resources/offset.md.tmpl exp-templates/resources/offset.md.tmpl +cmpenv templates/resources/rotating.md.tmpl exp-templates/resources/rotating.md.tmpl +cmpenv templates/resources/sleep.md.tmpl exp-templates/resources/sleep.md.tmpl +cmpenv templates/resources/static.md.tmpl exp-templates/resources/static.md.tmpl + +# Check generated example files +cmpenv examples/example_1.tf examples/example_1.tf + +cmpenv examples/functions/rfc3339_parse/example_1.tf exp-examples/functions/rfc3339_parse/example_1.tf + +cmpenv examples/resources/offset/example_1.tf exp-examples/resources/offset/example_1.tf +cmpenv examples/resources/offset/example_2.tf exp-examples/resources/offset/example_2.tf +cmpenv examples/resources/offset/import_1.sh exp-examples/resources/offset/import_1.sh + +cmpenv examples/resources/rotating/example_1.tf exp-examples/resources/rotating/example_1.tf +cmpenv examples/resources/rotating/import_1.sh exp-examples/resources/rotating/import_1.sh +cmpenv examples/resources/rotating/import_2.sh exp-examples/resources/rotating/import_2.sh + +cmpenv examples/resources/sleep/example_1.tf exp-examples/resources/sleep/example_1.tf +cmpenv examples/resources/sleep/example_2.tf exp-examples/resources/sleep/example_2.tf +cmpenv examples/resources/sleep/example_3.tf exp-examples/resources/sleep/example_3.tf +cmpenv examples/resources/sleep/import_1.sh exp-examples/resources/sleep/import_1.sh +cmpenv examples/resources/sleep/import_2.sh exp-examples/resources/sleep/import_2.sh + +cmpenv examples/resources/static/example_1.tf examples/resources/static/example_1.tf +cmpenv examples/resources/static/example_2.tf examples/resources/static/example_2.tf +cmpenv examples/resources/static/import_1.sh examples/resources/static/import_1.sh + +# Verify legacy website directory is removed +! exists website/ + +-- expected-output.txt -- +migrating website from "$WORK/website/docs" to "$WORK/templates" +migrating functons directory: functions +migrating file "time_rfc3339_parse.html.markdown" +extracting YAML frontmatter to "$WORK/templates/functions/rfc3339_parse.md.tmpl" +extracting code examples from "time_rfc3339_parse.html.markdown" +creating example file "$WORK/examples/functions/rfc3339_parse/example_1.tf" +skipping code block with unknown language "text" +finished creating template "$WORK/templates/functions/rfc3339_parse.md.tmpl" +migrating provider index: index.html.markdown +migrating file "index.html.markdown" +extracting YAML frontmatter to "$WORK/templates/index.md.tmpl" +extracting code examples from "index.html.markdown" +creating example file "$WORK/examples/example_1.tf" +finished creating template "$WORK/templates/index.md.tmpl" +migrating resources directory: r +migrating file "time_offset.html.markdown" +extracting YAML frontmatter to "$WORK/templates/resources/offset.md.tmpl" +extracting code examples from "time_offset.html.markdown" +creating example file "$WORK/examples/resources/offset/example_1.tf" +creating example file "$WORK/examples/resources/offset/example_2.tf" +creating import file "$WORK/examples/resources/offset/import_1.sh" +finished creating template "$WORK/templates/resources/offset.md.tmpl" +migrating file "time_rotating.html.markdown" +extracting YAML frontmatter to "$WORK/templates/resources/rotating.md.tmpl" +extracting code examples from "time_rotating.html.markdown" +creating example file "$WORK/examples/resources/rotating/example_1.tf" +creating import file "$WORK/examples/resources/rotating/import_1.sh" +creating import file "$WORK/examples/resources/rotating/import_2.sh" +finished creating template "$WORK/templates/resources/rotating.md.tmpl" +migrating file "time_sleep.html.markdown" +extracting YAML frontmatter to "$WORK/templates/resources/sleep.md.tmpl" +extracting code examples from "time_sleep.html.markdown" +creating example file "$WORK/examples/resources/sleep/example_1.tf" +creating example file "$WORK/examples/resources/sleep/example_2.tf" +creating example file "$WORK/examples/resources/sleep/example_3.tf" +creating import file "$WORK/examples/resources/sleep/import_1.sh" +creating import file "$WORK/examples/resources/sleep/import_2.sh" +finished creating template "$WORK/templates/resources/sleep.md.tmpl" +migrating file "time_static.html.markdown" +extracting YAML frontmatter to "$WORK/templates/resources/static.md.tmpl" +extracting code examples from "time_static.html.markdown" +creating example file "$WORK/examples/resources/static/example_1.tf" +creating example file "$WORK/examples/resources/static/example_2.tf" +creating import file "$WORK/examples/resources/static/import_1.sh" +finished creating template "$WORK/templates/resources/static.md.tmpl" +-- website/docs/index.html.markdown -- +--- +layout: "time" +page_title: "Provider: Time" +description: |- + The time provider is used to interact with time-based resources. +--- + +# Time Provider + +The time provider is used to interact with time-based resources. The provider itself has no configuration options. + +Use the navigation to the left to read about the available resources. + +## Resource "Triggers" + +Certain time resources, only perform actions during specific lifecycle actions: + +- `time_offset`: Saves base timestamp into Terraform state only when created. +- `time_sleep`: Sleeps when created and/or destroyed. +- `time_static`: Saves base timestamp into Terraform state only when created. + +These resources provide an optional map argument called `triggers` that can be populated with arbitrary key/value pairs. When the keys or values of this argument are updated, Terraform will re-perform the desired action, such as updating the base timestamp or sleeping again. + +For example: + +```hcl +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +`triggers` are *not* treated as sensitive attributes; a value used for `triggers` will be displayed in Terraform UI output as plaintext. + +To force a these actions to reoccur without updating `triggers`, the [`terraform taint` command](https://www.terraform.io/docs/commands/taint.html) can be used to produce the action on the next run. +-- website/docs/functions/time_rfc3339_parse.html.markdown -- +--- +page_title: "rfc3339_parse Function - Time" +subcategory: "" +description: |- + Parse an RFC3339 timestamp string +--- + +# rfc3339_parse Function + +Given an RFC3339 timestamp string, will parse and return an object representation of that date and time. + +## Example Usage + +```terraform +output "test" { + value = provider::time::rfc3339_parse("2023-07-25T23:43:16-00:00") +} +``` + +## Signature + +```text +rfc3339_parse(timestamp string) Object +``` + +## Arguments + +1. `timestamp` (string) RFC3339 timestamp string to parse +-- website/docs/r/time_offset.html.markdown -- +--- +layout: "time" +page_title: "Time: time_offset" +description: |- + Manages a offset time resource. +--- + +# Resource: time_offset + +Manages an offset time resource, which keeps an UTC timestamp stored in the Terraform state that is offset from a locally sourced base timestamp. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +```hcl +resource "time_offset" "example" { + offset_days = 7 +} + +output "one_week_from_now" { + value = time_offset.example.rfc3339 +} +``` + +### Triggers Usage + +```hcl +resource "time_offset" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } + + offset_days = 7 +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_offset resource to ensure that + # both will change together. + ami = time_offset.ami_update.triggers.ami_id + + tags = { + ExpirationTime = time_offset.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +## Argument Reference + +~> **NOTE:** At least one of the `offset_` arguments must be configured. + +The following arguments are optional: + +* `base_rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `offset_days` - (Optional) Number of days to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_hours` - (Optional) Number of hours to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_minutes` - (Optional) Number of minutes to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_months` - (Optional) Number of months to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_seconds` - (Optional) Number of seconds to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_years` - (Optional) Number of years to offset the base timestamp. Conflicts with other `offset_` arguments. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of offset timestamp. +* `hour` - Number hour of offset timestamp. +* `id` - UTC RFC3339 format of the base timestamp, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of offset timestamp. +* `month` - Number month of offset timestamp. +* `rfc3339` - UTC RFC3339 format of the offset timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of offset timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of offset timestamp. + +## Import + +This resource can be imported using the base UTC RFC3339 timestamp and offset years, months, days, hours, minutes, and seconds, separated by commas (`,`), e.g. + +```console +$ terraform import time_offset.example 2020-02-12T06:36:13Z,0,0,7,0,0,0 +``` + +The `triggers` argument cannot be imported. +-- website/docs/r/time_rotating.html.markdown -- +--- +layout: "time" +page_title: "Time: time_rotating" +description: |- + Manages a rotating time resource. +--- + +# Resource: time_rotating + +Manages a rotating time resource, which keeps a rotating UTC timestamp stored in the Terraform state and proposes resource recreation when the locally sourced current time is beyond the rotation time. This rotation only occurs when Terraform is executed, meaning there will be drift between the rotation timestamp and actual rotation. The new rotation timestamp offset includes this drift. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html) by only forcing a new value on the set cadence. + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +This example configuration will rotate (destroy/create) the resource every 30 days. + +```hcl +resource "time_rotating" "example" { + rotation_days = 30 +} +``` + +## Argument Reference + +~> **NOTE:** At least one of the `rotation_` arguments must be configured. + +The following arguments are optional: + +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. +* `rotation_days` - (Optional) Number of days to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_hours` - (Optional) Number of hours to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_minutes` - (Optional) Number of minutes to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_months` - (Optional) Number of months to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_rfc3339` - (Optional) Configure the rotation timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_years` - (Optional) Number of years to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. These conditions recreate the resource in addition to other rotation arguments. See [the main provider documentation](../index.html) for more information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 format of the base timestamp, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the base UTC RFC3339 value and rotation years, months, days, hours, and minutes, separated by commas (`,`), e.g. for 30 days + +```console +$ terraform import time_rotation.example 2020-02-12T06:36:13Z,0,0,30,0,0 +``` + +Otherwise, to import with the rotation RFC3339 value, the base UTC RFC3339 value and rotation UTC RFC3339 value, separated by commas (`,`), e.g. + +```console +$ terraform import time_rotation.example 2020-02-12T06:36:13Z,2020-02-13T06:36:13Z +``` + +The `triggers` argument cannot be imported. +-- website/docs/r/time_sleep.html.markdown -- +--- +layout: "time" +page_title: "Time: time_sleep" +description: |- + Manages a static time resource. +--- + +# Resource: time_sleep + +Manages a resource that delays creation and/or destruction, typically for further resources. This prevents cross-platform compatibility and destroy-time issues with using the [`local-exec` provisioner](https://www.terraform.io/docs/provisioners/local-exec.html). + +-> In many cases, this resource should be considered a workaround for issues that should be reported and handled in downstream Terraform Provider logic. Downstream resources can usually introduce or adjust retries in their code to handle time delay issues for all Terraform configurations or upstream resources can be improved to better wait for a resource to be fully ready and available. + +## Example Usage + +### Delay Create Usage + +```hcl +# This resource will destroy (potentially immediately) after null_resource.next +resource "null_resource" "previous" {} + +resource "time_sleep" "wait_30_seconds" { + depends_on = [null_resource.previous] + + create_duration = "30s" +} + +# This resource will create (at least) 30 seconds after null_resource.previous +resource "null_resource" "next" { + depends_on = [time_sleep.wait_30_seconds] +} +``` + +### Delay Destroy Usage + +```hcl +# This resource will destroy (at least) 30 seconds after null_resource.next +resource "null_resource" "previous" {} + +resource "time_sleep" "wait_30_seconds" { + depends_on = [null_resource.previous] + + destroy_duration = "30s" +} + +# This resource will create (potentially immediately) after null_resource.previous +resource "null_resource" "next" { + depends_on = [time_sleep.wait_30_seconds] +} +``` + +### Triggers Usage + +```hcl +resource "aws_ram_resource_association" "example" { + resource_arn = aws_subnet.example.arn + resource_share_arn = aws_ram_resource_share.example.arn +} + +# AWS resources shared via Resource Access Manager can take a few seconds to +# propagate across AWS accounts after RAM returns a successful association. +resource "time_sleep" "ram_resource_propagation" { + create_duration = "60s" + + triggers = { + # This sets up a proper dependency on the RAM association + subnet_arn = aws_ram_resource_association.example.resource_arn + subnet_id = aws_subnet.example.id + } +} + +resource "aws_db_subnet_group" "example" { + name = "example" + + # Read the Subnet identifier "through" the time_sleep resource to ensure a + # proper dependency and that both will change together. + subnet_ids = [time_sleep.ram_resource_propagation.triggers["subnet_id"]] +} +``` + +## Argument Reference + +The following arguments are optional: + +* `create_duration` - (Optional) [Time duration][1] to delay resource creation. For example, `30s` for 30 seconds or `5m` for 5 minutes. Updating this value by itself will not trigger a delay. +* `destroy_duration` - (Optional) [Time duration][1] to delay resource destroy. For example, `30s` for 30 seconds or `5m` for 5 minutes. Updating this value by itself will not trigger a delay. This value or any updates to it must be successfully applied into the Terraform state before destroying this resource to take effect. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will run any creation or destroy delays again. See [the main provider documentation](../index.html) for more information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - UTC RFC3339 timestamp of the creation or import, e.g. `2020-02-12T06:36:13Z`. + +## Import + +This resource can be imported with the `create_duration` and `destroy_duration`, separated by a comma (`,`). + +e.g. For 30 seconds create duration with no destroy duration: + +```console +$ terraform import time_sleep.example 30s, +``` + +e.g. For 30 seconds destroy duration with no create duration: + +```console +$ terraform import time_sleep.example ,30s +``` + +The `triggers` argument cannot be imported. + +[1]: https://golang.org/pkg/time/#ParseDuration +-- website/docs/r/time_static.html.markdown -- +--- +layout: "time" +page_title: "Time: time_static" +description: |- + Manages a static time resource. +--- + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +```hcl +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +``` + +### Triggers Usage + +```hcl +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +```console +$ terraform import time_static.example 2020-02-12T06:36:13Z +``` + +The `triggers` argument cannot be imported. + +-- exp-examples/example_1.tf -- +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/functions/rfc3339_parse/example_1.tf -- +output "test" { + value = provider::time::rfc3339_parse("2023-07-25T23:43:16-00:00") +} +-- exp-examples/resources/offset/example_1.tf -- +resource "time_offset" "example" { + offset_days = 7 +} + +output "one_week_from_now" { + value = time_offset.example.rfc3339 +} +-- exp-examples/resources/offset/example_2.tf -- +resource "time_offset" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } + + offset_days = 7 +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_offset resource to ensure that + # both will change together. + ami = time_offset.ami_update.triggers.ami_id + + tags = { + ExpirationTime = time_offset.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/resources/offset/import_1.sh -- +$ terraform import time_offset.example 2020-02-12T06:36:13Z,0,0,7,0,0,0 +-- exp-examples/resources/rotating/example_1.tf -- +resource "time_rotating" "example" { + rotation_days = 30 +} +-- exp-examples/resources/rotating/import_1.sh -- +$ terraform import time_rotation.example 2020-02-12T06:36:13Z,0,0,30,0,0 +-- exp-examples/resources/rotating/import_2.sh -- +$ terraform import time_rotation.example 2020-02-12T06:36:13Z,2020-02-13T06:36:13Z +-- exp-examples/resources/sleep/example_1.tf -- +# This resource will destroy (potentially immediately) after null_resource.next +resource "null_resource" "previous" {} + +resource "time_sleep" "wait_30_seconds" { + depends_on = [null_resource.previous] + + create_duration = "30s" +} + +# This resource will create (at least) 30 seconds after null_resource.previous +resource "null_resource" "next" { + depends_on = [time_sleep.wait_30_seconds] +} +-- exp-examples/resources/sleep/example_2.tf -- +# This resource will destroy (at least) 30 seconds after null_resource.next +resource "null_resource" "previous" {} + +resource "time_sleep" "wait_30_seconds" { + depends_on = [null_resource.previous] + + destroy_duration = "30s" +} + +# This resource will create (potentially immediately) after null_resource.previous +resource "null_resource" "next" { + depends_on = [time_sleep.wait_30_seconds] +} +-- exp-examples/resources/sleep/example_3.tf -- +resource "aws_ram_resource_association" "example" { + resource_arn = aws_subnet.example.arn + resource_share_arn = aws_ram_resource_share.example.arn +} + +# AWS resources shared via Resource Access Manager can take a few seconds to +# propagate across AWS accounts after RAM returns a successful association. +resource "time_sleep" "ram_resource_propagation" { + create_duration = "60s" + + triggers = { + # This sets up a proper dependency on the RAM association + subnet_arn = aws_ram_resource_association.example.resource_arn + subnet_id = aws_subnet.example.id + } +} + +resource "aws_db_subnet_group" "example" { + name = "example" + + # Read the Subnet identifier "through" the time_sleep resource to ensure a + # proper dependency and that both will change together. + subnet_ids = [time_sleep.ram_resource_propagation.triggers["subnet_id"]] +} +-- exp-examples/resources/sleep/import_1.sh -- +$ terraform import time_sleep.example 30s, +-- exp-examples/resources/sleep/import_2.sh -- +$ terraform import time_sleep.example ,30s +-- exp-examples/resources/static/example_1.tf -- +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +-- exp-examples/resources/static/example_2.tf -- +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/resources/static/import_1.sh -- +$ terraform import time_static.example 2020-02-12T06:36:13Z +-- exp-templates/index.md.tmpl -- +--- +page_title: "Provider: Time" +description: |- + The time provider is used to interact with time-based resources. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# Time Provider + +The time provider is used to interact with time-based resources. The provider itself has no configuration options. + +Use the navigation to the left to read about the available resources. + +## Resource "Triggers" + +Certain time resources, only perform actions during specific lifecycle actions: + +- `time_offset`: Saves base timestamp into Terraform state only when created. +- `time_sleep`: Sleeps when created and/or destroyed. +- `time_static`: Saves base timestamp into Terraform state only when created. + +These resources provide an optional map argument called `triggers` that can be populated with arbitrary key/value pairs. When the keys or values of this argument are updated, Terraform will re-perform the desired action, such as updating the base timestamp or sleeping again. + +For example: + +{{tffile "examples/example_1.tf"}} + +`triggers` are *not* treated as sensitive attributes; a value used for `triggers` will be displayed in Terraform UI output as plaintext. + +To force a these actions to reoccur without updating `triggers`, the [`terraform taint` command](https://www.terraform.io/docs/commands/taint.html) can be used to produce the action on the next run. +-- exp-templates/functions/rfc3339_parse.md.tmpl -- +--- +page_title: "rfc3339_parse Function - Time" +subcategory: "" +description: |- + Parse an RFC3339 timestamp string +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .FunctionArgumentsMarkdown }} template can be used to replace manual argument documentation if descriptions of function arguments are added in the provider source code. */ -}} + +# rfc3339_parse Function + +Given an RFC3339 timestamp string, will parse and return an object representation of that date and time. + +## Example Usage + +{{tffile "examples/functions/rfc3339_parse/example_1.tf"}} + +## Signature + +```text +rfc3339_parse(timestamp string) Object +``` + +## Arguments + +1. `timestamp` (string) RFC3339 timestamp string to parse +-- exp-templates/resources/offset.md.tmpl -- +--- +page_title: "Time: time_offset" +description: |- + Manages a offset time resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# Resource: time_offset + +Manages an offset time resource, which keeps an UTC timestamp stored in the Terraform state that is offset from a locally sourced base timestamp. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +{{tffile "examples/resources/offset/example_1.tf"}} + +### Triggers Usage + +{{tffile "examples/resources/offset/example_2.tf"}} + +## Argument Reference + +~> **NOTE:** At least one of the `offset_` arguments must be configured. + +The following arguments are optional: + +* `base_rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `offset_days` - (Optional) Number of days to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_hours` - (Optional) Number of hours to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_minutes` - (Optional) Number of minutes to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_months` - (Optional) Number of months to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_seconds` - (Optional) Number of seconds to offset the base timestamp. Conflicts with other `offset_` arguments. +* `offset_years` - (Optional) Number of years to offset the base timestamp. Conflicts with other `offset_` arguments. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of offset timestamp. +* `hour` - Number hour of offset timestamp. +* `id` - UTC RFC3339 format of the base timestamp, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of offset timestamp. +* `month` - Number month of offset timestamp. +* `rfc3339` - UTC RFC3339 format of the offset timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of offset timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of offset timestamp. + +## Import + +This resource can be imported using the base UTC RFC3339 timestamp and offset years, months, days, hours, minutes, and seconds, separated by commas (`,`), e.g. + +{{codefile "shell" "examples/resources/offset/import_1.sh"}} + +The `triggers` argument cannot be imported. +-- exp-templates/resources/rotating.md.tmpl -- +--- +page_title: "Time: time_rotating" +description: |- + Manages a rotating time resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# Resource: time_rotating + +Manages a rotating time resource, which keeps a rotating UTC timestamp stored in the Terraform state and proposes resource recreation when the locally sourced current time is beyond the rotation time. This rotation only occurs when Terraform is executed, meaning there will be drift between the rotation timestamp and actual rotation. The new rotation timestamp offset includes this drift. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html) by only forcing a new value on the set cadence. + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +This example configuration will rotate (destroy/create) the resource every 30 days. + +{{tffile "examples/resources/rotating/example_1.tf"}} + +## Argument Reference + +~> **NOTE:** At least one of the `rotation_` arguments must be configured. + +The following arguments are optional: + +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. +* `rotation_days` - (Optional) Number of days to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_hours` - (Optional) Number of hours to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_minutes` - (Optional) Number of minutes to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_months` - (Optional) Number of months to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_rfc3339` - (Optional) Configure the rotation timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `rotation_years` - (Optional) Number of years to add to the base timestamp to configure the rotation timestamp. When the current time has passed the rotation timestamp, the resource will trigger recreation. Conflicts with other `rotation_` arguments. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. These conditions recreate the resource in addition to other rotation arguments. See [the main provider documentation](../index.html) for more information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 format of the base timestamp, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the base UTC RFC3339 value and rotation years, months, days, hours, and minutes, separated by commas (`,`), e.g. for 30 days + +{{codefile "shell" "examples/resources/rotating/import_1.sh"}} + +Otherwise, to import with the rotation RFC3339 value, the base UTC RFC3339 value and rotation UTC RFC3339 value, separated by commas (`,`), e.g. + +{{codefile "shell" "examples/resources/rotating/import_2.sh"}} + +The `triggers` argument cannot be imported. +-- exp-templates/resources/sleep.md.tmpl -- +--- +page_title: "Time: time_sleep" +description: |- + Manages a static time resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# Resource: time_sleep + +Manages a resource that delays creation and/or destruction, typically for further resources. This prevents cross-platform compatibility and destroy-time issues with using the [`local-exec` provisioner](https://www.terraform.io/docs/provisioners/local-exec.html). + +-> In many cases, this resource should be considered a workaround for issues that should be reported and handled in downstream Terraform Provider logic. Downstream resources can usually introduce or adjust retries in their code to handle time delay issues for all Terraform configurations or upstream resources can be improved to better wait for a resource to be fully ready and available. + +## Example Usage + +### Delay Create Usage + +{{tffile "examples/resources/sleep/example_1.tf"}} + +### Delay Destroy Usage + +{{tffile "examples/resources/sleep/example_2.tf"}} + +### Triggers Usage + +{{tffile "examples/resources/sleep/example_3.tf"}} + +## Argument Reference + +The following arguments are optional: + +* `create_duration` - (Optional) [Time duration](https://golang.org/pkg/time/#ParseDuration) to delay resource creation. For example, `30s` for 30 seconds or `5m` for 5 minutes. Updating this value by itself will not trigger a delay. +* `destroy_duration` - (Optional) [Time duration](https://golang.org/pkg/time/#ParseDuration) to delay resource destroy. For example, `30s` for 30 seconds or `5m` for 5 minutes. Updating this value by itself will not trigger a delay. This value or any updates to it must be successfully applied into the Terraform state before destroying this resource to take effect. +* `triggers` - (Optional) Arbitrary map of values that, when changed, will run any creation or destroy delays again. See [the main provider documentation](../index.html) for more information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - UTC RFC3339 timestamp of the creation or import, e.g. `2020-02-12T06:36:13Z`. + +## Import + +This resource can be imported with the `create_duration` and `destroy_duration`, separated by a comma (`,`). + +e.g. For 30 seconds create duration with no destroy duration: + +{{codefile "shell" "examples/resources/sleep/import_1.sh"}} + +e.g. For 30 seconds destroy duration with no create duration: + +{{codefile "shell" "examples/resources/sleep/import_2.sh"}} + +The `triggers` argument cannot be imported. +-- exp-templates/resources/static.md.tmpl -- +--- +page_title: "Time: time_static" +description: |- + Manages a static time resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +{{tffile "examples/resources/static/example_1.tf"}} + +### Triggers Usage + +{{tffile "examples/resources/static/example_2.tf"}} + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +{{codefile "shell" "examples/resources/static/import_1.sh"}} + +The `triggers` argument cannot be imported. \ No newline at end of file diff --git a/internal/cmd/migrate.go b/internal/cmd/migrate.go index 8248b9ec..d0e9ca3a 100644 --- a/internal/cmd/migrate.go +++ b/internal/cmd/migrate.go @@ -17,6 +17,7 @@ type migrateCmd struct { flagProviderDir string flagTemplatesDir string flagExamplesDir string + flagProviderName string } func (cmd *migrateCmd) Synopsis() string { @@ -67,6 +68,8 @@ func (cmd *migrateCmd) Flags() *flag.FlagSet { fs.StringVar(&cmd.flagProviderDir, "provider-dir", "", "relative or absolute path to the root provider code directory; this will default to the current working directory if not set") fs.StringVar(&cmd.flagTemplatesDir, "templates-dir", "templates", "new website templates directory based on provider-dir; files will be migrated to this directory") fs.StringVar(&cmd.flagExamplesDir, "examples-dir", "examples", "examples directory based on provider-dir; extracted code examples will be migrated to this directory") + fs.StringVar(&cmd.flagProviderName, "provider-name", "", "provider name, as used in Terraform configurations; this will default to provider-dir basename if not set") + return fs } @@ -87,6 +90,7 @@ func (cmd *migrateCmd) runInternal() error { cmd.flagProviderDir, cmd.flagTemplatesDir, cmd.flagExamplesDir, + cmd.flagProviderName, ) if err != nil { return fmt.Errorf("unable to migrate website: %w", err) diff --git a/internal/provider/migrate.go b/internal/provider/migrate.go index e36c0c7f..abd1f976 100644 --- a/internal/provider/migrate.go +++ b/internal/provider/migrate.go @@ -27,6 +27,8 @@ type migrator struct { templatesDir string examplesDir string + providerName string + ui cli.Ui } @@ -38,7 +40,7 @@ func (m *migrator) warnf(format string, a ...interface{}) { m.ui.Warn(fmt.Sprintf(format, a...)) } -func Migrate(ui cli.Ui, providerDir string, templatesDir string, examplesDir string) error { +func Migrate(ui cli.Ui, providerDir string, templatesDir string, examplesDir string, providerName string) error { // Ensure provider directory is resolved absolute path if providerDir == "" { wd, err := os.Getwd() @@ -69,6 +71,11 @@ func Migrate(ui cli.Ui, providerDir string, templatesDir string, examplesDir str return fmt.Errorf("expected %q to be a directory", providerDir) } + // Default providerName to provider directory name + if providerName == "" { + providerName = filepath.Base(providerDir) + } + // Determine website directory websiteDir, err := determineWebsiteDir(providerDir) if err != nil { @@ -80,6 +87,7 @@ func Migrate(ui cli.Ui, providerDir string, templatesDir string, examplesDir str templatesDir: templatesDir, examplesDir: examplesDir, websiteDir: websiteDir, + providerName: providerName, ui: ui, } @@ -172,14 +180,16 @@ func (m *migrator) MigrateTemplate(relDir string) fs.WalkDirFunc { } baseName, _, _ := strings.Cut(d.Name(), ".") + shortName := providerShortName(m.providerName) + fileName := strings.TrimPrefix(baseName, shortName+"_") var exampleRelDir string - if baseName == "index" { + if fileName == "index" { exampleRelDir = relDir } else { - exampleRelDir = filepath.Join(relDir, baseName) + exampleRelDir = filepath.Join(relDir, fileName) } - templateFilePath := filepath.Join(m.ProviderTemplatesDir(), relDir, baseName+".md.tmpl") + templateFilePath := filepath.Join(m.ProviderTemplatesDir(), relDir, fileName+".md.tmpl") err = os.MkdirAll(filepath.Dir(templateFilePath), 0755) if err != nil {