Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Waypoint: Require TF Project ID to be set, instead of a terraform_cloud_workspace_details resource #1052

Merged
merged 13 commits into from
Aug 21, 2024
Merged
5 changes: 5 additions & 0 deletions .changelog/1052.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
```release-note:improvement
Waypoint resources for templates and add-on definitions no longer require setting
a `terraform_cloud_workspace_details` resource, and instead can be set by the
`terraform_project_id` param.
```
3 changes: 2 additions & 1 deletion docs/resources/waypoint_add_on_definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ Waypoint Add-on Definition resource
- `name` (String) The name of the Add-on Definition.
- `summary` (String) A short summary of the Add-on Definition.
- `terraform_no_code_module_source` (String) Terraform Cloud no-code Module Source, expected to be in one of the following formats: "app.terraform.io/hcp_waypoint_example/ecs-advanced-microservice/aws" or "private/hcp_waypoint_example/ecs-advanced-microservice/aws"
- `terraform_project_id` (String) The ID of the Terraform Cloud Project to create workspaces in. The ID is found on the Terraform Cloud Project settings page.

### Optional

- `labels` (List of String) List of labels attached to this Add-on Definition.
- `project_id` (String) The ID of the HCP project where the Waypoint Add-on Definition is located.
- `readme_markdown_template` (String) The markdown template for the Add-on Definition README (markdown format supported).
- `terraform_cloud_workspace_details` (Attributes) Terraform Cloud Workspace details. If not provided, defaults to the HCP Terraform project of the associated application. (see [below for nested schema](#nestedatt--terraform_cloud_workspace_details))
- `terraform_cloud_workspace_details` (Attributes, Deprecated) Terraform Cloud Workspace details. If not provided, defaults to the HCP Terraform project of the associated application. (see [below for nested schema](#nestedatt--terraform_cloud_workspace_details))
- `variable_options` (Attributes Set) List of variable options for the Add-on Definition. (see [below for nested schema](#nestedatt--variable_options))

### Read-Only
Expand Down
3 changes: 2 additions & 1 deletion docs/resources/waypoint_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ Waypoint Template resource

- `name` (String) The name of the Template.
- `summary` (String) A brief description of the template, up to 110 characters
- `terraform_cloud_workspace_details` (Attributes) Terraform Cloud Workspace details (see [below for nested schema](#nestedatt--terraform_cloud_workspace_details))
- `terraform_no_code_module_source` (String) Terraform Cloud No-Code Module details
- `terraform_project_id` (String) The ID of the Terraform Cloud Project to create workspaces in. The ID is found on the Terraform Cloud Project settings page.

### Optional

- `description` (String) A description of the template, along with when and why it should be used, up to 500 characters
- `labels` (List of String) List of labels attached to this Template.
- `project_id` (String) The ID of the HCP project where the Waypoint Template is located.
- `readme_markdown_template` (String) Instructions for using the template (markdown format supported).
- `terraform_cloud_workspace_details` (Attributes, Deprecated) Terraform Cloud Workspace details (see [below for nested schema](#nestedatt--terraform_cloud_workspace_details))
- `variable_options` (Attributes Set) List of variable options for the template (see [below for nested schema](#nestedatt--variable_options))

### Read-Only
Expand Down
79 changes: 53 additions & 26 deletions internal/provider/waypoint/resource_waypoint_add_on_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type AddOnDefinitionResourceModel struct {
Description types.String `tfsdk:"description"`
ReadmeMarkdownTemplate types.String `tfsdk:"readme_markdown_template"`

TerraformProjectID types.String `tfsdk:"terraform_project_id"`
TerraformCloudWorkspace types.Object `tfsdk:"terraform_cloud_workspace_details"`
TerraformNoCodeModuleSource types.String `tfsdk:"terraform_no_code_module_source"`
TerraformVariableOptions []*tfcVariableOption `tfsdk:"variable_options"`
Expand Down Expand Up @@ -109,9 +110,17 @@ func (r *AddOnDefinitionResource) Schema(ctx context.Context, req resource.Schem
Description: "The markdown template for the Add-on Definition README (markdown format supported).",
Optional: true,
},
"terraform_project_id": schema.StringAttribute{
Required: true,
Description: "The ID of the Terraform Cloud Project to create workspaces in. The ID is found on the Terraform Cloud Project settings page.",
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"terraform_cloud_workspace_details": &schema.SingleNestedAttribute{
Optional: true,
Computed: true,
DeprecationMessage: "terraform_cloud_workspace_details is deprecated, use terraform_project_id instead",
briancain marked this conversation as resolved.
Show resolved Hide resolved
Optional: true,
Computed: true,
Description: "Terraform Cloud Workspace details. If not provided, defaults to " +
"the HCP Terraform project of the associated application.",
Attributes: map[string]schema.Attribute{
Expand Down Expand Up @@ -254,31 +263,40 @@ func (r *AddOnDefinitionResource) Create(ctx context.Context, req resource.Creat
VariableOptions: varOpts,
}

// Decode the base64 encoded readme markdown template to see if it is encoded
readmeBytes, err := base64.StdEncoding.DecodeString(plan.ReadmeMarkdownTemplate.ValueString())
// If there is an error, we assume that it is because the string is not encoded. This is ok and
// we will just use the string as is in the ReadmeTemplate field of the model.
// Eventually the ReadMeMarkdownTemplate field will be deprecated, so the default behavior will be to
// expect the readme to not be encoded
if err != nil {
modelBody.ReadmeTemplate = plan.ReadmeMarkdownTemplate.ValueString()
} else {
modelBody.ReadmeMarkdownTemplate = readmeBytes
}

if !plan.TerraformCloudWorkspace.IsNull() && !plan.TerraformCloudWorkspace.IsUnknown() {
briancain marked this conversation as resolved.
Show resolved Hide resolved
workspaceDetails := &tfcWorkspace{}
diags := plan.TerraformCloudWorkspace.As(ctx, workspaceDetails, basetypes.ObjectAsOptions{})
if diags.HasError() {
resp.Diagnostics.Append(diags...)
return
}

if workspaceDetails.Name.IsNull() {
// Set a default if none provided
workspaceDetails.Name = plan.Name
}
if workspaceDetails.TerraformProjectID.IsNull() {
// Set a default if none provided
workspaceDetails.TerraformProjectID = plan.TerraformProjectID
}
modelBody.TerraformCloudWorkspaceDetails = &waypointModels.HashicorpCloudWaypointTerraformCloudWorkspaceDetails{
Name: workspaceDetails.Name.ValueString(),
ProjectID: workspaceDetails.TerraformProjectID.ValueString(),
}
}

// Decode the base64 encoded readme markdown template to see if it is encoded
readmeBytes, err := base64.StdEncoding.DecodeString(plan.ReadmeMarkdownTemplate.ValueString())
// If there is an error, we assume that it is because the string is not encoded. This is ok and
// we will just use the string as is in the ReadmeTemplate field of the model.
// Eventually the ReadMeMarkdownTemplate field will be deprecated, so the default behavior will be to
// expect the readme to not be encoded
if err != nil {
modelBody.ReadmeTemplate = plan.ReadmeMarkdownTemplate.ValueString()
} else {
modelBody.ReadmeMarkdownTemplate = readmeBytes
}

params := &waypoint_service.WaypointServiceCreateAddOnDefinitionParams{
NamespaceID: ns.ID,
Body: modelBody,
Expand Down Expand Up @@ -498,31 +516,40 @@ func (r *AddOnDefinitionResource) Update(ctx context.Context, req resource.Updat
VariableOptions: varOpts,
}

// Decode the base64 encoded readme markdown template to see if it is encoded
readmeBytes, err := base64.StdEncoding.DecodeString(plan.ReadmeMarkdownTemplate.ValueString())
// If there is an error, we assume that it is because the string is not encoded. This is ok and
// we will just use the string as is in the ReadmeTemplate field of the model.
// Eventually the ReadMeMarkdownTemplate field will be deprecated, so the default behavior will be to
// expect the readme to not be encoded
if err != nil {
modelBody.ReadmeTemplate = plan.ReadmeMarkdownTemplate.ValueString()
} else {
modelBody.ReadmeMarkdownTemplate = readmeBytes
}

if !plan.TerraformCloudWorkspace.IsNull() && !plan.TerraformCloudWorkspace.IsUnknown() {
briancain marked this conversation as resolved.
Show resolved Hide resolved
workspaceDetails := &tfcWorkspace{}
diags := plan.TerraformCloudWorkspace.As(ctx, workspaceDetails, basetypes.ObjectAsOptions{})
if diags.HasError() {
resp.Diagnostics.Append(diags...)
return
}

if workspaceDetails.Name.IsNull() {
// Set a default if none provided
workspaceDetails.Name = plan.Name
}
if workspaceDetails.TerraformProjectID.IsNull() {
// Grab the top level project ID if this was not provided
workspaceDetails.TerraformProjectID = plan.TerraformProjectID
}
modelBody.TerraformCloudWorkspaceDetails = &waypointModels.HashicorpCloudWaypointTerraformCloudWorkspaceDetails{
Name: workspaceDetails.Name.ValueString(),
ProjectID: workspaceDetails.TerraformProjectID.ValueString(),
}
}

// Decode the base64 encoded readme markdown template to see if it is encoded
readmeBytes, err := base64.StdEncoding.DecodeString(plan.ReadmeMarkdownTemplate.ValueString())
// If there is an error, we assume that it is because the string is not encoded. This is ok and
// we will just use the string as is in the ReadmeTemplate field of the model.
// Eventually the ReadMeMarkdownTemplate field will be deprecated, so the default behavior will be to
// expect the readme to not be encoded
if err != nil {
modelBody.ReadmeTemplate = plan.ReadmeMarkdownTemplate.ValueString()
} else {
modelBody.ReadmeMarkdownTemplate = readmeBytes
}

params := &waypoint_service.WaypointServiceUpdateAddOnDefinitionParams{
NamespaceID: ns.ID,
Body: modelBody,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,15 @@ resource "hcp_waypoint_add_on_definition" "test" {
name = %q
summary = "some summary for fun"
description = "some description for fun"
terraform_no_code_module = "private/waypoint-tfc-testing/waypoint-template-starter/null"
terraform_no_code_module_source = "private/waypoint-tfc-testing/waypoint-template-starter/null"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
}
variable_options = [
{
name = "string_variable"
{
name = "string_variable"
variable_type = "string"
options = [
"b"
Expand Down
42 changes: 24 additions & 18 deletions internal/provider/waypoint/resource_waypoint_add_on_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ resource "hcp_waypoint_template" "test" {
summary = "some summary for fun"
readme_markdown_template = base64encode("# Some Readme")
terraform_no_code_module_source = "private/waypoint-tfc-testing/waypoint-template-starter/null"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
Expand All @@ -208,6 +209,7 @@ resource "hcp_waypoint_add_on_definition" "test" {
summary = "some summary for fun"
description = "some description for fun"
terraform_no_code_module_source = "private/waypoint-tfc-testing/waypoint-template-starter/null"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
Expand All @@ -228,6 +230,7 @@ resource "hcp_waypoint_template" "test" {
summary = "some summary for fun"
readme_markdown_template = base64encode("# Some Readme")
terraform_no_code_module_source = "private/waypoint-tfc-testing/waypoint-template-starter/null"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
Expand All @@ -246,28 +249,29 @@ resource "hcp_waypoint_add_on_definition" "test_var_opts" {
description = "some description for fun"
readme_markdown_template = base64encode("# Some Readme")
terraform_no_code_module_source = "private/waypoint-tfc-testing/waypoint-vault-dweller/null"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
}
labels = ["fallout", "vault-tec"]
variable_options = [
{
name = "vault_dweller_name"
{
name = "vault_dweller_name"
variable_type = "string"
user_editable = true
options = [
options = [
"lucy",
"courier",
"lone-wanderer",
"sole-survivor",
]
},
{
name = "faction"
name = "faction"
variable_type = "string"
user_editable = true
options = [
options = [
"ncr",
"brotherhood-of-steel",
"caesars-legion",
Expand All @@ -284,16 +288,16 @@ resource "hcp_waypoint_add_on" "test_var_opts" {
application_id = hcp_waypoint_application.test.id

add_on_input_variables = [
{
name = "faction"
{
name = "faction"
variable_type = "string"
value = "brotherhood-of-steel"
value = "brotherhood-of-steel"
},
{
name = "vault_dweller_name"
name = "vault_dweller_name"
variable_type = "string"
value = "courier"
}
value = "courier"
}
]
}

Expand All @@ -307,6 +311,7 @@ resource "hcp_waypoint_template" "test" {
summary = "some summary for fun"
readme_markdown_template = base64encode("# Some Readme")
terraform_no_code_module_source = "private/waypoint-tfc-testing/waypoint-template-starter/null"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
Expand All @@ -324,34 +329,35 @@ resource "hcp_waypoint_add_on_definition" "test_var_opts" {
summary = "some summary for fun"
description = "some description"
readme_markdown_template = base64encode("# Some Readme")
terraform_no_code_module = "private/waypoint-tfc-testing/waypoint-vault-dweller/null"
terraform_no_code_module_source = "private/waypoint-tfc-testing/waypoint-vault-dweller/null"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
}
labels = ["fallout", "vault-tec"]
variable_options = [
{
name = "vault_dweller_name"
{
name = "vault_dweller_name"
variable_type = "string"
user_editable = false
options = [
options = [
"lone-wanderer",
]
},
{
name = "faction"
name = "faction"
variable_type = "string"
user_editable = false
options = [
options = [
"brotherhood-of-steel",
]
},
]
}

resource "hcp_waypoint_add_on" "test_var_opts" {
name = "%s"
name = "%s"
definition_id = hcp_waypoint_add_on_definition.test_var_opts.id
application_id = hcp_waypoint_application.test.id
}`, tempName, appName, defName, addOnName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,8 @@ resource "hcp_waypoint_template" "test" {
name = "%s"
summary = "some summary for fun"
readme_markdown_template = base64encode("# Some Readme")
terraform_no_code_module = {
source = "private/waypoint-tfc-testing/waypoint-template-starter/null"
version = "0.0.2"
}
terraform_no_code_module_source = "private/waypoint-tfc-testing/waypoint-template-starter/null"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
Expand All @@ -216,6 +214,7 @@ resource "hcp_waypoint_template" "test_var_opts" {
summary = "some summary for fun"
readme_markdown_template = base64encode("# Some Readme")
terraform_no_code_module_source = "private/waypoint-tfc-testing/waypoint-vault-dweller/null"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
Expand Down Expand Up @@ -274,25 +273,26 @@ resource "hcp_waypoint_template" "test_var_opts" {
summary = "some summary for fun"
readme_markdown_template = base64encode("# Some Readme")
terraform_no_code_module_source = "private/waypoint-tfc-testing/waypoint-vault-dweller/null"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
}
labels = ["fallout", "vault-tec"]
variable_options = [
{
name = "vault_dweller_name"
{
name = "vault_dweller_name"
variable_type = "string"
user_editable = false
options = [
options = [
"lone-wanderer",
]
},
{
name = "faction"
name = "faction"
variable_type = "string"
user_editable = false
options = [
options = [
"brotherhood-of-steel",
]
},
Expand Down
Loading