Opsworks Application support
This commit is contained in:
parent
f1638097e5
commit
6bf9f21c39
|
@ -199,6 +199,7 @@ func Provider() terraform.ResourceProvider {
|
|||
"aws_network_acl": resourceAwsNetworkAcl(),
|
||||
"aws_network_acl_rule": resourceAwsNetworkAclRule(),
|
||||
"aws_network_interface": resourceAwsNetworkInterface(),
|
||||
"aws_opsworks_application": resourceAwsOpsworksApplication(),
|
||||
"aws_opsworks_stack": resourceAwsOpsworksStack(),
|
||||
"aws_opsworks_java_app_layer": resourceAwsOpsworksJavaAppLayer(),
|
||||
"aws_opsworks_haproxy_layer": resourceAwsOpsworksHaproxyLayer(),
|
||||
|
|
|
@ -0,0 +1,603 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/opsworks"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceAwsOpsworksApplication() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
|
||||
Create: resourceAwsOpsworksApplicationCreate,
|
||||
Read: resourceAwsOpsworksApplicationRead,
|
||||
Update: resourceAwsOpsworksApplicationUpdate,
|
||||
Delete: resourceAwsOpsworksApplicationDelete,
|
||||
Schema: map[string]*schema.Schema{
|
||||
"id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"short_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
},
|
||||
// aws-flow-ruby | java | rails | php | nodejs | static | other
|
||||
"type": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"stack_id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
// TODO: the following 4 vals are really part of the Attributes array. We should validate that only ones relevant to the chosen type are set, perhaps. (what is the default type? how do they map?)
|
||||
"document_root": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
//Default: "public",
|
||||
},
|
||||
"rails_env": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
//Default: "production",
|
||||
},
|
||||
"auto_bundle_on_deploy": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
//Default: true,
|
||||
},
|
||||
"aws_flow_ruby_settings": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"app_source": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"type": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"url": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"username": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"password": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"revision": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"ssh_key": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// AutoSelectOpsworksMysqlInstance, OpsworksMysqlInstance, or RdsDbInstance.
|
||||
// anything beside auto select will lead into failure in case the instance doesn't exist
|
||||
// XXX: validation?
|
||||
"data_source_type": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"data_source_database_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"data_source_arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"description": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"domains": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
"environment": &schema.Schema{
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"key": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"value": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"secure": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"enable_ssl": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
},
|
||||
"ssl_configuration": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
//Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"certificate": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
StateFunc: func(v interface{}) string {
|
||||
switch v.(type) {
|
||||
case string:
|
||||
return strings.TrimSpace(v.(string))
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
},
|
||||
},
|
||||
"private_key": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
StateFunc: func(v interface{}) string {
|
||||
switch v.(type) {
|
||||
case string:
|
||||
return strings.TrimSpace(v.(string))
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
},
|
||||
},
|
||||
"chain": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
StateFunc: func(v interface{}) string {
|
||||
switch v.(type) {
|
||||
case string:
|
||||
return strings.TrimSpace(v.(string))
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksApplicationValidate(d *schema.ResourceData) error {
|
||||
appSourceCount := d.Get("app_source.#").(int)
|
||||
if appSourceCount > 1 {
|
||||
return fmt.Errorf("Only one app_source is permitted.")
|
||||
}
|
||||
|
||||
sslCount := d.Get("ssl_configuration.#").(int)
|
||||
if sslCount > 1 {
|
||||
return fmt.Errorf("Only one ssl_configuration is permitted.")
|
||||
}
|
||||
|
||||
if d.Get("type").(string) == opsworks.AppTypeRails {
|
||||
if _, ok := d.GetOk("rails_env"); !ok {
|
||||
return fmt.Errorf("Set rails_env must be set if type is set to rails.")
|
||||
}
|
||||
}
|
||||
switch d.Get("type").(string) {
|
||||
case opsworks.AppTypeStatic:
|
||||
case opsworks.AppTypeRails:
|
||||
case opsworks.AppTypePhp:
|
||||
case opsworks.AppTypeOther:
|
||||
case opsworks.AppTypeNodejs:
|
||||
case opsworks.AppTypeJava:
|
||||
case opsworks.AppTypeAwsFlowRuby:
|
||||
log.Printf("[DEBUG] type supported")
|
||||
default:
|
||||
return fmt.Errorf("opsworks_application.type must be one of %s, %s, %s, %s, %s, %s, %s",
|
||||
opsworks.AppTypeStatic,
|
||||
opsworks.AppTypeRails,
|
||||
opsworks.AppTypePhp,
|
||||
opsworks.AppTypeOther,
|
||||
opsworks.AppTypeNodejs,
|
||||
opsworks.AppTypeJava,
|
||||
opsworks.AppTypeAwsFlowRuby)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksApplicationRead(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*AWSClient).opsworksconn
|
||||
|
||||
req := &opsworks.DescribeAppsInput{
|
||||
AppIds: []*string{
|
||||
aws.String(d.Id()),
|
||||
},
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Reading OpsWorks app: %s", d.Id())
|
||||
|
||||
resp, err := client.DescribeApps(req)
|
||||
if err != nil {
|
||||
if awserr, ok := err.(awserr.Error); ok {
|
||||
if awserr.Code() == "ResourceNotFoundException" {
|
||||
log.Printf("[INFO] App not found: %s", d.Id())
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
app := resp.Apps[0]
|
||||
|
||||
d.Set("name", app.Name)
|
||||
d.Set("stack_id", app.StackId)
|
||||
d.Set("type", app.Type)
|
||||
d.Set("description", app.Description)
|
||||
d.Set("domains", flattenStringList(app.Domains))
|
||||
d.Set("enable_ssl", app.EnableSsl)
|
||||
resourceAwsOpsworksSetApplicationSsl(d, app.SslConfiguration)
|
||||
resourceAwsOpsworksSetApplicationSource(d, app.AppSource)
|
||||
resourceAwsOpsworksSetApplicationDataSources(d, app.DataSources)
|
||||
resourceAwsOpsworksSetApplicationEnvironmentVariable(d, app.Environment)
|
||||
resourceAwsOpsworksSetApplicationAttributes(d, app.Attributes)
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksApplicationCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*AWSClient).opsworksconn
|
||||
|
||||
err := resourceAwsOpsworksApplicationValidate(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req := &opsworks.CreateAppInput{
|
||||
Name: aws.String(d.Get("name").(string)),
|
||||
Shortname: aws.String(d.Get("short_name").(string)),
|
||||
StackId: aws.String(d.Get("stack_id").(string)),
|
||||
Type: aws.String(d.Get("type").(string)),
|
||||
Description: aws.String(d.Get("description").(string)),
|
||||
Domains: expandStringList(d.Get("domains").([]interface{})),
|
||||
EnableSsl: aws.Bool(d.Get("enable_ssl").(bool)),
|
||||
SslConfiguration: resourceAwsOpsworksApplicationSsl(d),
|
||||
AppSource: resourceAwsOpsworksApplicationSource(d),
|
||||
DataSources: resourceAwsOpsworksApplicationDataSources(d),
|
||||
Environment: resourceAwsOpsworksApplicationEnvironmentVariable(d),
|
||||
Attributes: resourceAwsOpsworksApplicationAttributes(d),
|
||||
}
|
||||
|
||||
var resp *opsworks.CreateAppOutput
|
||||
err = resource.Retry(2*time.Minute, func() *resource.RetryError {
|
||||
var cerr error
|
||||
resp, cerr = client.CreateApp(req)
|
||||
if cerr != nil {
|
||||
log.Printf("[INFO] client error")
|
||||
if opserr, ok := cerr.(awserr.Error); ok {
|
||||
// XXX: handle errors
|
||||
log.Printf("[ERROR] OpsWorks error: %s message: %s", opserr.Code(), opserr.Message())
|
||||
return resource.RetryableError(cerr)
|
||||
}
|
||||
return resource.NonRetryableError(cerr)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
appID := *resp.AppId
|
||||
d.SetId(appID)
|
||||
d.Set("id", appID)
|
||||
|
||||
return resourceAwsOpsworksApplicationRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksApplicationUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*AWSClient).opsworksconn
|
||||
|
||||
req := &opsworks.UpdateAppInput{
|
||||
AppId: aws.String(d.Id()),
|
||||
Name: aws.String(d.Get("name").(string)),
|
||||
Type: aws.String(d.Get("type").(string)),
|
||||
Description: aws.String(d.Get("description").(string)),
|
||||
Domains: expandStringList(d.Get("domains").([]interface{})),
|
||||
EnableSsl: aws.Bool(d.Get("enable_ssl").(bool)),
|
||||
SslConfiguration: resourceAwsOpsworksApplicationSsl(d),
|
||||
AppSource: resourceAwsOpsworksApplicationSource(d),
|
||||
DataSources: resourceAwsOpsworksApplicationDataSources(d),
|
||||
Environment: resourceAwsOpsworksApplicationEnvironmentVariable(d),
|
||||
Attributes: resourceAwsOpsworksApplicationAttributes(d),
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Updating OpsWorks layer: %s", d.Id())
|
||||
|
||||
var resp *opsworks.UpdateAppOutput
|
||||
err := resource.Retry(2*time.Minute, func() *resource.RetryError {
|
||||
var cerr error
|
||||
resp, cerr = client.UpdateApp(req)
|
||||
if cerr != nil {
|
||||
log.Printf("[INFO] client error")
|
||||
if opserr, ok := cerr.(awserr.Error); ok {
|
||||
// XXX: handle errors
|
||||
log.Printf("[ERROR] OpsWorks error: %s message: %s", opserr.Code(), opserr.Message())
|
||||
return resource.NonRetryableError(cerr)
|
||||
}
|
||||
return resource.RetryableError(cerr)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return resourceAwsOpsworksApplicationRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksApplicationDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*AWSClient).opsworksconn
|
||||
|
||||
req := &opsworks.DeleteAppInput{
|
||||
AppId: aws.String(d.Id()),
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Deleting OpsWorks application: %s", d.Id())
|
||||
|
||||
_, err := client.DeleteApp(req)
|
||||
return err
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksSetApplicationEnvironmentVariable(d *schema.ResourceData, v []*opsworks.EnvironmentVariable) {
|
||||
log.Printf("[DEBUG] envs: %s %d", v, len(v))
|
||||
if len(v) == 0 {
|
||||
d.Set("environment", nil)
|
||||
return
|
||||
}
|
||||
newValue := make([]*map[string]interface{}, len(v))
|
||||
|
||||
for i := 0; i < len(v); i++ {
|
||||
config := v[i]
|
||||
data := make(map[string]interface{})
|
||||
newValue[i] = &data
|
||||
|
||||
if config.Key != nil {
|
||||
data["key"] = *config.Key
|
||||
}
|
||||
if config.Value != nil {
|
||||
data["value"] = *config.Value
|
||||
}
|
||||
if config.Secure != nil {
|
||||
|
||||
if bool(*config.Secure) {
|
||||
data["secure"] = &opsworksTrueString
|
||||
} else {
|
||||
data["secure"] = &opsworksFalseString
|
||||
}
|
||||
}
|
||||
log.Printf("[DEBUG] v: %s", data)
|
||||
}
|
||||
|
||||
d.Set("environment", newValue)
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksApplicationEnvironmentVariable(d *schema.ResourceData) []*opsworks.EnvironmentVariable {
|
||||
environmentVariables := d.Get("environment").(*schema.Set).List()
|
||||
result := make([]*opsworks.EnvironmentVariable, len(environmentVariables))
|
||||
|
||||
for i := 0; i < len(environmentVariables); i++ {
|
||||
env := environmentVariables[i].(map[string]interface{})
|
||||
|
||||
result[i] = &opsworks.EnvironmentVariable{
|
||||
Key: aws.String(env["key"].(string)),
|
||||
Value: aws.String(env["value"].(string)),
|
||||
Secure: aws.Bool(env["secure"].(bool)),
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksApplicationSource(d *schema.ResourceData) *opsworks.Source {
|
||||
count := d.Get("app_source.#").(int)
|
||||
if count == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &opsworks.Source{
|
||||
Type: aws.String(d.Get("app_source.0.type").(string)),
|
||||
Url: aws.String(d.Get("app_source.0.url").(string)),
|
||||
Username: aws.String(d.Get("app_source.0.username").(string)),
|
||||
Password: aws.String(d.Get("app_source.0.password").(string)),
|
||||
Revision: aws.String(d.Get("app_source.0.revision").(string)),
|
||||
SshKey: aws.String(d.Get("app_source.0.ssh_key").(string)),
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksSetApplicationSource(d *schema.ResourceData, v *opsworks.Source) {
|
||||
nv := make([]interface{}, 0, 1)
|
||||
if v != nil {
|
||||
m := make(map[string]interface{})
|
||||
if v.Type != nil {
|
||||
m["type"] = *v.Type
|
||||
}
|
||||
if v.Url != nil {
|
||||
m["url"] = *v.Url
|
||||
}
|
||||
if v.Username != nil {
|
||||
m["username"] = *v.Username
|
||||
}
|
||||
if v.Password != nil {
|
||||
m["password"] = *v.Password
|
||||
}
|
||||
if v.Revision != nil {
|
||||
m["revision"] = *v.Revision
|
||||
}
|
||||
if v.SshKey != nil {
|
||||
m["ssh_key"] = *v.SshKey
|
||||
}
|
||||
nv = append(nv, m)
|
||||
}
|
||||
|
||||
err := d.Set("app_source", nv)
|
||||
if err != nil {
|
||||
// should never happen
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksApplicationDataSources(d *schema.ResourceData) []*opsworks.DataSource {
|
||||
arn := d.Get("data_source_arn").(string)
|
||||
databaseName := d.Get("data_source_database_name").(string)
|
||||
databaseType := d.Get("data_source_type").(string)
|
||||
|
||||
result := make([]*opsworks.DataSource, 1)
|
||||
|
||||
if len(arn) > 0 || len(databaseName) > 0 || len(databaseType) > 0 {
|
||||
result[0] = &opsworks.DataSource{
|
||||
Arn: aws.String(arn),
|
||||
DatabaseName: aws.String(databaseName),
|
||||
Type: aws.String(databaseType),
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksSetApplicationDataSources(d *schema.ResourceData, v []*opsworks.DataSource) {
|
||||
d.Set("data_source_arn", nil)
|
||||
d.Set("data_source_database_name", nil)
|
||||
d.Set("data_source_type", nil)
|
||||
|
||||
if len(v) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
d.Set("data_source_arn", v[0].Arn)
|
||||
d.Set("data_source_database_name", v[0].DatabaseName)
|
||||
d.Set("data_source_type", v[0].Type)
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksApplicationSsl(d *schema.ResourceData) *opsworks.SslConfiguration {
|
||||
count := d.Get("ssl_configuration.#").(int)
|
||||
if count == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &opsworks.SslConfiguration{
|
||||
PrivateKey: aws.String(d.Get("ssl_configuration.0.private_key").(string)),
|
||||
Certificate: aws.String(d.Get("ssl_configuration.0.certificate").(string)),
|
||||
Chain: aws.String(d.Get("ssl_configuration.0.chain").(string)),
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksSetApplicationSsl(d *schema.ResourceData, v *opsworks.SslConfiguration) {
|
||||
nv := make([]interface{}, 0, 1)
|
||||
set := false
|
||||
if v != nil {
|
||||
m := make(map[string]interface{})
|
||||
if v.PrivateKey != nil {
|
||||
m["private_key"] = *v.PrivateKey
|
||||
set = true
|
||||
}
|
||||
if v.Certificate != nil {
|
||||
m["certificate"] = *v.Certificate
|
||||
set = true
|
||||
}
|
||||
if v.Chain != nil {
|
||||
m["chain"] = *v.Chain
|
||||
set = true
|
||||
}
|
||||
if set {
|
||||
nv = append(nv, m)
|
||||
}
|
||||
}
|
||||
|
||||
err := d.Set("ssl_configuration", nv)
|
||||
if err != nil {
|
||||
// should never happen
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksApplicationAttributes(d *schema.ResourceData) map[string]*string {
|
||||
if d.Get("type") != opsworks.AppTypeRails {
|
||||
return nil
|
||||
}
|
||||
attributes := make(map[string]*string)
|
||||
|
||||
if val := d.Get("document_root").(string); len(val) > 0 {
|
||||
attributes[opsworks.AppAttributesKeysDocumentRoot] = aws.String(val)
|
||||
}
|
||||
if val := d.Get("aws_flow_ruby_settings").(string); len(val) > 0 {
|
||||
attributes[opsworks.AppAttributesKeysAwsFlowRubySettings] = aws.String(val)
|
||||
}
|
||||
if val := d.Get("rails_env").(string); len(val) > 0 {
|
||||
attributes[opsworks.AppAttributesKeysRailsEnv] = aws.String(val)
|
||||
}
|
||||
if val := d.Get("auto_bundle_on_deploy").(string); len(val) > 0 {
|
||||
if val == "1" {
|
||||
val = "true"
|
||||
} else if val == "0" {
|
||||
val = "false"
|
||||
}
|
||||
attributes[opsworks.AppAttributesKeysAutoBundleOnDeploy] = aws.String(val)
|
||||
}
|
||||
|
||||
return attributes
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksSetApplicationAttributes(d *schema.ResourceData, v map[string]*string) {
|
||||
d.Set("document_root", nil)
|
||||
d.Set("rails_env", nil)
|
||||
d.Set("aws_flow_ruby_settings", nil)
|
||||
d.Set("auto_bundle_on_deploy", nil)
|
||||
|
||||
if d.Get("type") != opsworks.AppTypeRails {
|
||||
return
|
||||
}
|
||||
if val, ok := v[opsworks.AppAttributesKeysDocumentRoot]; ok {
|
||||
d.Set("document_root", val)
|
||||
}
|
||||
if val, ok := v[opsworks.AppAttributesKeysAwsFlowRubySettings]; ok {
|
||||
d.Set("aws_flow_ruby_settings", val)
|
||||
}
|
||||
if val, ok := v[opsworks.AppAttributesKeysRailsEnv]; ok {
|
||||
d.Set("rails_env", val)
|
||||
}
|
||||
if val, ok := v[opsworks.AppAttributesKeysAutoBundleOnDeploy]; ok {
|
||||
d.Set("auto_bundle_on_deploy", val)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/opsworks"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccAWSOpsworksApplication(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAwsOpsworksApplicationDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAwsOpsworksApplicationCreate,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "name", "tf-ops-acc-application",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "type", "other",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "enable_ssl", "false",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "ssl_configuration", "",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "domains", "",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "app_source", "",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "environment.3077298702.key", "key1",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "environment.3077298702.value", "value1",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "environment.3077298702.secret", "",
|
||||
),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccAwsOpsworksApplicationUpdate,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "name", "tf-ops-acc-application",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "type", "rails",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "enable_ssl", "true",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "ssl_configuration.0.certificate", "-----BEGIN CERTIFICATE-----\nMIIBkDCB+gIJALoScFD0sJq3MA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAYTAkRF\nMB4XDTE1MTIxOTIwMzU1MVoXDTE2MDExODIwMzU1MVowDTELMAkGA1UEBhMCREUw\ngZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKKQKbTTH/Julz16xY7ArYlzJYCP\nedTCx1bopuryCx/+d1gC94MtRdlPSpQl8mfc9iBdtXbJppp73Qh/DzLzO9Ns25xZ\n+kUQMhbIyLsaCBzuEGLgAaVdGpNvRBw++UoYtd0U7QczFAreTGLH8n8+FIzuI5Mc\n+MJ1TKbbt5gFfRSzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEALARo96wCDmaHKCaX\nS0IGLGnZCfiIUfCmBxOXBSJxDBwter95QHR0dMGxYIujee5n4vvavpVsqZnfMC3I\nOZWPlwiUJbNIpK+04Bg2vd5m/NMMrvi75RfmyeMtSfq/NrIX2Q3+nyWI7DLq7yZI\nV/YEvOqdAiy5NEWBztHx8HvB9G4=\n-----END CERTIFICATE-----",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "ssl_configuration.0.private_key", "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQCikCm00x/ybpc9esWOwK2JcyWAj3nUwsdW6Kbq8gsf/ndYAveD\nLUXZT0qUJfJn3PYgXbV2yaaae90Ifw8y8zvTbNucWfpFEDIWyMi7Gggc7hBi4AGl\nXRqTb0QcPvlKGLXdFO0HMxQK3kxix/J/PhSM7iOTHPjCdUym27eYBX0UswIDAQAB\nAoGBAIYcrvuqDboguI8U4TUjCkfSAgds1pLLWk79wu8jXkA329d1IyNKT0y3WIye\nPbyoEzmidZmZROQ/+ZsPz8c12Y0DrX73WSVzKNyJeP7XMk9HSzA1D9RX0U0S+5Kh\nFAMc2NEVVFIfQtVtoVmHdKDpnRYtOCHLW9rRpvqOOjd4mYk5AkEAzeiFr1mtlnsa\n67shMxzDaOTAFMchRz6G7aSovvCztxcB63ulFI/w9OTUMdTQ7ff7pet+lVihLc2W\nefIL0HvsjQJBAMocNTKaR/TnsV5GSk2kPAdR+zFP5sQy8sfMy0lEXTylc7zN4ajX\nMeHVoxp+GZgpfDcZ3ya808H1umyXh+xA1j8CQE9x9ZKQYT98RAjL7KVR5btk9w+N\nPTPF1j1+mHUDXfO4ds8qp6jlWKzEVXLcj7ghRADiebaZuaZ4eiSW1SQdjEkCQQC4\nwDhQ3X9RfEpCp3ZcqvjEqEg6t5N3XitYQPjDLN8eBRBbUsgpEy3iBuxl10eGNMX7\niIbYXlwkPYAArDPv3wT5AkAwp4vym+YKmDqh6gseKfRDuJqRiW9yD5A8VGr/w88k\n5rkuduVGP7tK3uIp00Its3aEyKF8mLGWYszVGeeLxAMH\n-----END RSA PRIVATE KEY-----",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "domains.0", "example.com",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "domains.1", "sub.example.com",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "app_source.0.password", "",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "app_source.0.revision", "master",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "app_source.0.ssh_key", "",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "app_source.0.type", "git",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "app_source.0.url", "https://github.com/aws/example.git",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "app_source.0.username", "",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "environment.2107898637.key", "key2",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "environment.2107898637.value", "value2",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "environment.2107898637.secure", "true",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "environment.3077298702.key", "key1",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "environment.3077298702.value", "value1",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "environment.3077298702.secret", "",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "document_root", "root",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "auto_bundle_on_deploy", "true",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_application.tf-acc-app", "rails_env", "staging",
|
||||
),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckAwsOpsworksApplicationDestroy(s *terraform.State) error {
|
||||
client := testAccProvider.Meta().(*AWSClient).opsworksconn
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "aws_opsworks_application" {
|
||||
continue
|
||||
}
|
||||
|
||||
req := &opsworks.DescribeAppsInput{
|
||||
AppIds: []*string{
|
||||
aws.String(rs.Primary.ID),
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := client.DescribeApps(req)
|
||||
if err == nil {
|
||||
if len(resp.Apps) > 0 {
|
||||
return fmt.Errorf("OpsWorks App still exist.")
|
||||
}
|
||||
}
|
||||
|
||||
if awserr, ok := err.(awserr.Error); ok {
|
||||
if awserr.Code() != "ResourceNotFoundException" {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var testAccAwsOpsworksApplicationCreate = testAccAwsOpsworksStackConfigNoVpcCreate("") + `
|
||||
resource "aws_opsworks_application" "tf-acc-app" {
|
||||
stack_id = "${aws_opsworks_stack.tf-acc.id}"
|
||||
name = "tf-ops-acc-application"
|
||||
type = "other"
|
||||
enable_ssl = false
|
||||
app_source ={
|
||||
type = "other"
|
||||
}
|
||||
environment = { key = "key1" value = "value1" secure = false}
|
||||
}
|
||||
`
|
||||
|
||||
var testAccAwsOpsworksApplicationUpdate = testAccAwsOpsworksStackConfigNoVpcCreate("") + `
|
||||
resource "aws_opsworks_application" "tf-acc-app" {
|
||||
stack_id = "${aws_opsworks_stack.tf-acc.id}"
|
||||
name = "tf-ops-acc-application"
|
||||
type = "rails"
|
||||
domains = ["example.com", "sub.example.com"]
|
||||
enable_ssl = true
|
||||
ssl_configuration = {
|
||||
private_key = <<EOS
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQCikCm00x/ybpc9esWOwK2JcyWAj3nUwsdW6Kbq8gsf/ndYAveD
|
||||
LUXZT0qUJfJn3PYgXbV2yaaae90Ifw8y8zvTbNucWfpFEDIWyMi7Gggc7hBi4AGl
|
||||
XRqTb0QcPvlKGLXdFO0HMxQK3kxix/J/PhSM7iOTHPjCdUym27eYBX0UswIDAQAB
|
||||
AoGBAIYcrvuqDboguI8U4TUjCkfSAgds1pLLWk79wu8jXkA329d1IyNKT0y3WIye
|
||||
PbyoEzmidZmZROQ/+ZsPz8c12Y0DrX73WSVzKNyJeP7XMk9HSzA1D9RX0U0S+5Kh
|
||||
FAMc2NEVVFIfQtVtoVmHdKDpnRYtOCHLW9rRpvqOOjd4mYk5AkEAzeiFr1mtlnsa
|
||||
67shMxzDaOTAFMchRz6G7aSovvCztxcB63ulFI/w9OTUMdTQ7ff7pet+lVihLc2W
|
||||
efIL0HvsjQJBAMocNTKaR/TnsV5GSk2kPAdR+zFP5sQy8sfMy0lEXTylc7zN4ajX
|
||||
MeHVoxp+GZgpfDcZ3ya808H1umyXh+xA1j8CQE9x9ZKQYT98RAjL7KVR5btk9w+N
|
||||
PTPF1j1+mHUDXfO4ds8qp6jlWKzEVXLcj7ghRADiebaZuaZ4eiSW1SQdjEkCQQC4
|
||||
wDhQ3X9RfEpCp3ZcqvjEqEg6t5N3XitYQPjDLN8eBRBbUsgpEy3iBuxl10eGNMX7
|
||||
iIbYXlwkPYAArDPv3wT5AkAwp4vym+YKmDqh6gseKfRDuJqRiW9yD5A8VGr/w88k
|
||||
5rkuduVGP7tK3uIp00Its3aEyKF8mLGWYszVGeeLxAMH
|
||||
-----END RSA PRIVATE KEY-----
|
||||
EOS
|
||||
certificate = <<EOS
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBkDCB+gIJALoScFD0sJq3MA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAYTAkRF
|
||||
MB4XDTE1MTIxOTIwMzU1MVoXDTE2MDExODIwMzU1MVowDTELMAkGA1UEBhMCREUw
|
||||
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKKQKbTTH/Julz16xY7ArYlzJYCP
|
||||
edTCx1bopuryCx/+d1gC94MtRdlPSpQl8mfc9iBdtXbJppp73Qh/DzLzO9Ns25xZ
|
||||
+kUQMhbIyLsaCBzuEGLgAaVdGpNvRBw++UoYtd0U7QczFAreTGLH8n8+FIzuI5Mc
|
||||
+MJ1TKbbt5gFfRSzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEALARo96wCDmaHKCaX
|
||||
S0IGLGnZCfiIUfCmBxOXBSJxDBwter95QHR0dMGxYIujee5n4vvavpVsqZnfMC3I
|
||||
OZWPlwiUJbNIpK+04Bg2vd5m/NMMrvi75RfmyeMtSfq/NrIX2Q3+nyWI7DLq7yZI
|
||||
V/YEvOqdAiy5NEWBztHx8HvB9G4=
|
||||
-----END CERTIFICATE-----
|
||||
EOS
|
||||
}
|
||||
app_source = {
|
||||
type = "git"
|
||||
revision = "master"
|
||||
url = "https://github.com/aws/example.git"
|
||||
}
|
||||
environment = { key = "key1" value = "value1" secure = false}
|
||||
environment = { key = "key2" value = "value2" }
|
||||
document_root = "root"
|
||||
auto_bundle_on_deploy = "true"
|
||||
rails_env = "staging"
|
||||
}
|
||||
`
|
|
@ -0,0 +1,94 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: aws_opsworks_aplication"
|
||||
sidebar_current: "docs-aws-resource-opsworks-application"
|
||||
description: |-
|
||||
Provides an OpsWorks application resource.
|
||||
---
|
||||
|
||||
# aws\_opsworks\_application
|
||||
|
||||
Provides an OpsWorks application resource.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "aws_opsworks_application" "foo-app" {
|
||||
name = "foobar application"
|
||||
short_name = "foobar"
|
||||
stack_id = "${aws_opsworks_stack.stack.id}"
|
||||
type = "rails"
|
||||
description = "This is a Rails application"
|
||||
domains = [
|
||||
"example.com",
|
||||
"sub.example.com"
|
||||
]
|
||||
environment = {
|
||||
key = "key"
|
||||
value = "value"
|
||||
secure = false
|
||||
}
|
||||
app_source = {
|
||||
type = "git"
|
||||
revision = "master"
|
||||
url = "https://github.com/example.git"
|
||||
}
|
||||
enable_ssl = true
|
||||
ssl_configuration = {
|
||||
private_key = "${file("./foobar.key")}"
|
||||
certificate = "${file("./foobar.crt")}"
|
||||
}
|
||||
document_root = "public"
|
||||
auto_bundle_on_deploy = true
|
||||
rails_env = "staging"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) A human-readable name for the application.
|
||||
* `short_name` - (Required) A short, machine-readable name for the application. This can only be defined on resource creation and ignored on resource update.
|
||||
* `stack_id` - (Required) The id of the stack the application will belong to.
|
||||
* `type` - (Required) Opsworks application type. One of `aws-flow-ruby`, `java`, `rails`, `php`, `nodejs`, `static` or `other`.
|
||||
* `description` - (Optional) A description of the app.
|
||||
* `environment` - (Optional) Object to define environment variables. Object is described below.
|
||||
* `enable_ssl` - (Optional) Whether to enable SSL for the app. This must be set in order to let `ssl_configuration.private_key`, `ssl_configuration.certificate` and `ssl_configuration.chain` take effect.
|
||||
* `ssl_configuration` - (Optional) The SSL configuration of the app. Object is described below.
|
||||
* `app_source` - (Optional) SCM configuration of the app as described below.
|
||||
* `data_source_arn` - (Optional) The data source's ARN.
|
||||
* `data_source_type` - (Optional) The data source's type one of `AutoSelectOpsworksMysqlInstance`, `OpsworksMysqlInstance`, or `RdsDbInstance`.
|
||||
* `data_source_database_name` - (Optional) The database name.
|
||||
* `domains` - (Optional) A list of virtual host alias.
|
||||
* `document_root` - (Optional) Subfolder for the document root for application of type `rails`.
|
||||
* `auto_bundle_on_deploy` - (Optional) Run bundle install when deploying for application of type `rails`.
|
||||
* `rails_env` - (Required if `type` = `rails`) The name of the Rails environment for application of type `rails`.
|
||||
* `aws_flow_ruby_settings` - (Optional) Specify activity and workflow workers for your app using the aws-flow gem.
|
||||
|
||||
An `app_source` block supports the following arguments (can only be defined once per resource):
|
||||
|
||||
* `type` - (Required) The type of source to use. For example, "archive".
|
||||
* `url` - (Required) The URL where the app resource can be found.
|
||||
* `username` - (Optional) Username to use when authenticating to the source.
|
||||
* `password` - (Optional) Password to use when authenticating to the source.
|
||||
* `ssh_key` - (Optional) SSH key to use when authenticating to the source.
|
||||
* `revision` - (Optional) For sources that are version-aware, the revision to use.
|
||||
|
||||
An `environment` block supports the following arguments:
|
||||
|
||||
* `key` - (Required) Variable name.
|
||||
* `value` - (Required) Variable value.
|
||||
* `secret` - (Optional) Set visibility of the variable value to `true` or `false`.
|
||||
|
||||
A `ssl_configuration` block supports the following arguments (can only be defined once per resource):
|
||||
|
||||
* `private_key` - (Required) The private key; the contents of the certificate's domain.key file.
|
||||
* `certificate` - (Required) The contents of the certificate's domain.crt file.
|
||||
* `chain` - (Optional) Can be used to specify an intermediate certificate authority key or client authentication.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The id of the application.
|
|
@ -498,6 +498,10 @@
|
|||
<a href="/docs/providers/aws/r/opsworks_static_web_layer.html">aws_opsworks_static_web_layer</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-aws-resource-opsworks-application") %>>
|
||||
<a href="/docs/providers/aws/r/opsworks_application.html">aws_opsworks_application</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
|
Loading…
Reference in New Issue