diff --git a/mysql/provider.go b/mysql/provider.go index 810e49767..e3e10fe79 100644 --- a/mysql/provider.go +++ b/mysql/provider.go @@ -1,6 +1,8 @@ package mysql import ( + "crypto/tls" + "crypto/x509" "database/sql" "fmt" "net" @@ -73,6 +75,11 @@ func Provider() terraform.ResourceProvider { Type: schema.TypeInt, Optional: true, }, + + "ssl_ca": { + Type: schema.TypeString, + Optional: true, + }, }, ResourcesMap: map[string]*schema.Resource{ @@ -96,12 +103,18 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { proto = "unix" } + var tlsConfig = d.Get("tls").(string) + var sslCa = d.Get("ssl_ca").(string) + if sslCa != "" && tlsConfig == "true" { + tlsConfig = "custom" + } + conf := mysql.Config{ User: d.Get("username").(string), Passwd: d.Get("password").(string), Net: proto, Addr: endpoint, - TLSConfig: d.Get("tls").(string), + TLSConfig: tlsConfig, AllowNativePasswords: true, } @@ -110,6 +123,19 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { return dialer.Dial("tcp", network) }) + if tlsConfig == "custom" { + rootCertPool := x509.NewCertPool() + sslCaBytes := []byte(sslCa) + if ok := rootCertPool.AppendCertsFromPEM(sslCaBytes); !ok { + return nil, fmt.Errorf("Could not read a valid PEM certificate") + } + + mysql.RegisterTLSConfig("custom", &tls.Config{ + RootCAs: rootCertPool, + InsecureSkipVerify: d.Get("tls").(string) == "skip-verify", + }) + } + return &MySQLConfiguration{ Config: &conf, MaxConnLifetime: time.Duration(d.Get("max_conn_lifetime_sec").(int)) * time.Second, @@ -160,6 +186,9 @@ func connectToMySQL(conf *MySQLConfiguration) (*sql.DB, error) { } err = db.Ping() + if err, ok := err.(x509.UnknownAuthorityError); ok { + return resource.NonRetryableError(err) + } if err != nil { return resource.RetryableError(err) } diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index e9232c044..2701206ad 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -82,3 +82,4 @@ The following arguments are supported: * `tls` - (Optional) The TLS configuration. One of `false`, `true`, or `skip-verify`. Defaults to `false`. * `max_conn_lifetime_sec` - (Optional) Sets the maximum amount of time a connection may be reused. If d <= 0, connections are reused forever. * `max_open_conns` - (Optional) Sets the maximum number of open connections to the database. If n <= 0, then there is no limit on the number of open connections. +* `ssl_ca` - (Optional) The contents of the PEM file of a CA. Used when the `tls` argument is set to `true`. \ No newline at end of file