diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 0d5aaf34b..de074064b 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -155,11 +155,13 @@ func (c *Communicator) Connect(o terraform.UIOutput) (err error) { " User: %s\n"+ " Password: %t\n"+ " Private key: %t\n"+ + " Certificate: %t\n"+ " SSH Agent: %t\n"+ " Checking Host Key: %t", c.connInfo.BastionHost, c.connInfo.BastionUser, c.connInfo.BastionPassword != "", c.connInfo.BastionPrivateKey != "", + c.connInfo.BastionCertificate != "", c.connInfo.Agent, c.connInfo.BastionHostKey != "", )) diff --git a/communicator/ssh/provisioner.go b/communicator/ssh/provisioner.go index 21d73b276..1c9d6f501 100644 --- a/communicator/ssh/provisioner.go +++ b/communicator/ssh/provisioner.go @@ -53,12 +53,13 @@ type connectionInfo struct { ScriptPath string `mapstructure:"script_path"` TimeoutVal time.Duration `mapstructure:"-"` - BastionUser string `mapstructure:"bastion_user"` - BastionPassword string `mapstructure:"bastion_password"` - BastionPrivateKey string `mapstructure:"bastion_private_key"` - BastionHost string `mapstructure:"bastion_host"` - BastionHostKey string `mapstructure:"bastion_host_key"` - BastionPort int `mapstructure:"bastion_port"` + BastionUser string `mapstructure:"bastion_user"` + BastionPassword string `mapstructure:"bastion_password"` + BastionPrivateKey string `mapstructure:"bastion_private_key"` + BastionCertificate string `mapstructure:"bastion_certificate"` + BastionHost string `mapstructure:"bastion_host"` + BastionHostKey string `mapstructure:"bastion_host_key"` + BastionPort int `mapstructure:"bastion_port"` AgentIdentity string `mapstructure:"agent_identity"` } @@ -123,6 +124,9 @@ func parseConnectionInfo(s *terraform.InstanceState) (*connectionInfo, error) { if connInfo.BastionPrivateKey == "" { connInfo.BastionPrivateKey = connInfo.PrivateKey } + if connInfo.BastionCertificate == "" { + connInfo.BastionCertificate = connInfo.Certificate + } if connInfo.BastionPort == 0 { connInfo.BastionPort = connInfo.Port } @@ -171,12 +175,13 @@ func prepareSSHConfig(connInfo *connectionInfo) (*sshConfig, error) { bastionHost := fmt.Sprintf("%s:%d", connInfo.BastionHost, connInfo.BastionPort) bastionConf, err = buildSSHClientConfig(sshClientConfigOpts{ - user: connInfo.BastionUser, - host: bastionHost, - privateKey: connInfo.BastionPrivateKey, - password: connInfo.BastionPassword, - hostKey: connInfo.HostKey, - sshAgent: sshAgent, + user: connInfo.BastionUser, + host: bastionHost, + privateKey: connInfo.BastionPrivateKey, + password: connInfo.BastionPassword, + hostKey: connInfo.HostKey, + certificate: connInfo.BastionCertificate, + sshAgent: sshAgent, }) if err != nil { return nil, err diff --git a/terraform/eval_validate.go b/terraform/eval_validate.go index 3edbee408..c6457f9ee 100644 --- a/terraform/eval_validate.go +++ b/terraform/eval_validate.go @@ -291,6 +291,10 @@ var connectionBlockSupersetSchema = &configschema.Block{ Type: cty.String, Optional: true, }, + "bastion_certificate": { + Type: cty.String, + Optional: true, + }, // For type=winrm only (enforced in winrm communicator) "https": { diff --git a/website/docs/provisioners/connection.html.markdown b/website/docs/provisioners/connection.html.markdown index ac59c5719..9bb511330 100644 --- a/website/docs/provisioners/connection.html.markdown +++ b/website/docs/provisioners/connection.html.markdown @@ -126,3 +126,7 @@ The `ssh` connection also supports the following fields to facilitate connnectio host. These can be loaded from a file on disk using [the `file` function](/docs/configuration/functions/file.html). Defaults to the value of the `private_key` field. + +* `bastion_certificate` - The contents of a signed CA Certificate. The certificate argument + must be used in conjunction with a `bastion_private_key`. These can be loaded from + a file on disk using the [the `file` function](/docs/configuration/functions/file.html). \ No newline at end of file