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

Support StringList for "aws_ssm_association" parameters | AWS-JoinDirectoryServiceDomain #16469

Open
ghost opened this issue Nov 27, 2020 · 10 comments
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/ssm Issues and PRs that pertain to the ssm service.

Comments

@ghost
Copy link

ghost commented Nov 27, 2020

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


Current Terraform Version

0.13.4

Use-cases

Currently terrform throws an error if more than one IP address is specified for AWS-JoinDirectoryServiceDomain, parameter "dnsIpAddresses" because only String Type is supported:

Elem: &schema.Schema{Type: schema.TypeString},

This is working, but only with a single IP specified:

resource "aws_ssm_association" "identifier" {
  name             = "AWS-JoinDirectoryServiceDomain"
  association_name = "JoinDirectoryServiceDomain"

  parameters = {
    directoryId    = "AWS-directory-ID"
    directoryName  = "DirectoryName"
    directoryOU    = "OU-DN"
    dnsIpAddresses = "198.51.100.1"
  }

  targets {
    key    = "InstanceIds"
    values = [aws_instance.<windows-instance>.id]
    }
}

Attempted Solutions

Because of the parameter name "dnsIpAddresses" a StringList should be supported:

dnsIpAddresses = ["198.51.100.1","198.51.100.2"]

Proposal

StringList should be in a format like ["198.51.100.1","198.51.100.2"]

resource "aws_ssm_association" "identifier" {
name             = "AWS-JoinDirectoryServiceDomain"
association_name = "JoinDirectoryServiceDomain"

parameters = {
    directoryId    = "AWS-directory-ID"
    directoryName  = "DirectoryName"
    directoryOU    = "OU-DN"
    dnsIpAddresses =  ["198.51.100.1","198.51.100.2"] 
   }

  targets {
    key    = "InstanceIds"
    values = [aws_instance.windows-instance.id]
    }
}

References

https://aws.amazon.com/de/blogs/security/how-to-configure-your-ec2-instances-to-automatically-join-a-microsoft-active-directory-domain/
https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-plugins.html#aws-domainJoin

Old. closed issue (why?):
#1889 (comment)

@ghost ghost added enhancement Requests to existing resources that expand the functionality or scope. service/ssm Issues and PRs that pertain to the ssm service. labels Nov 27, 2020
@github-actions github-actions bot added the needs-triage Waiting for first response or review from a maintainer. label Nov 27, 2020
@anGie44 anGie44 removed the needs-triage Waiting for first response or review from a maintainer. label Nov 30, 2020
@rp42mt
Copy link

rp42mt commented Mar 4, 2021

Do you have any update on that issue? Will it be fixed to list(string)? If yes, with which provider version?

@anthonyagresta
Copy link

This is indeed still absolutely a showstopper to actually using the aws_ssm_association resource.
I would love to see this fixed.

@tmccombs
Copy link
Contributor

Is there any workaround for this?

@tmccombs
Copy link
Contributor

It looks like the provider SDK still doesn't support a schema that accepts the equivalent of any (although I don't know why that is).

However, what if you could set the parametrs using a json string, so you could use jsonencode(...) to populate the data.

@jeremymcgee73
Copy link

I just ran into this as well. You can create the document with hard set parameters. But, thats not as nice. I am wanting to use an AWS managed SSM document.

@JordanLoehr
Copy link

JordanLoehr commented Oct 14, 2022

I've recently run into this too trying to use the AWS-RunShellCommand document, the commands parameter expects a StringList, but we can only pass a String value via terraform. Perhaps there is some weird history with this API, but its odd to me that the terraform provider set the value element type to just String in the first place, as the APIs for CreateAssociation, UpdateAssociation, and DescribeAssociation all take/return a StringList for any of the parameter map values.

"Parameters": { "string" : [ "string" ] },

Even in the current provider code, we see it takes our string value, and turns it into StringList with a single element (in the expandDocumentParameters function) to pass to the go SDK / AWS API:

"parameters": {
		Type:     schema.TypeMap,
		Optional: true,
		Computed: true,
		Elem:     &schema.Schema{Type: schema.TypeString},
	},
....
if v, ok := d.GetOk("parameters"); ok {
		associationInput.Parameters = expandDocumentParameters(v.(map[string]interface{}))
	}
....
func expandDocumentParameters(params map[string]interface{}) map[string][]*string {
	var docParams = make(map[string][]*string)
	for k, v := range params {
		values := make([]*string, 1)
		values[0] = aws.String(v.(string))
		docParams[k] = values
	}

	return docParams
}

Unfortunately this wasn't just StringList to begin with since it has to convert it internally, having it as string breaks the ability to use anything that legitimately needs a StringList. Unless the terraform provider sdk adds a Union or Any type schema, changing this to StringList will break backwards compatibility as any one using parameters with straight strings will need to update their templates to wrap it in a list themselves, eg:

resource "aws_ssm_association" "identifier" {
  name             = "AWS-JoinDirectoryServiceDomain"
  association_name = "JoinDirectoryServiceDomain"

  parameters = {
    directoryId    = ["AWS-directory-ID"]
    directoryName  = ["DirectoryName"]
    directoryOU    = ["OU-DN"]
    dnsIpAddresses = ["198.51.100.1"]
  }

  targets {
    key    = "InstanceIds"
    values = [aws_instance.<windows-instance>.id]
    }
}

@tmccombs
Copy link
Contributor

It could be done in a backwards compatible way by creating a new attribute and deprecating the current one.

@et304383
Copy link

Can we get an official answer on this one? This was designed wrong from the start, so you should fix it to be a proper list, and internally if you receive a string you convert to a list with one element, otherwise you pass the list as is. No backwards compatibility needed (no new fields please).

@tmccombs
Copy link
Contributor

if you receive a string you convert to a list with one element

Unfortunately, I don't think that is possible to do with the terraform provider API. The schema for a resource doesn't allow you to specify a union type or an any type. This is, IMO, a significant failing of the provider system.

@g-psantos
Copy link

FYI, a workaround that has worked for us is to create a separate aws_ssm_parameter resource of type StringList and then reference it in the aws_ssm_association parameters as {{ ssm:[parameter name] }}.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/ssm Issues and PRs that pertain to the ssm service.
Projects
None yet
Development

No branches or pull requests

8 participants