Merge branch 'master' of github.com:hashicorp/terraform
This commit is contained in:
commit
517f034562
|
@ -29,7 +29,10 @@ func resource_aws_elb_create(
|
||||||
|
|
||||||
// Expand the "listener" array to goamz compat []elb.Listener
|
// Expand the "listener" array to goamz compat []elb.Listener
|
||||||
v := flatmap.Expand(rs.Attributes, "listener").([]interface{})
|
v := flatmap.Expand(rs.Attributes, "listener").([]interface{})
|
||||||
listeners := expandListeners(v)
|
listeners, err := expandListeners(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
v = flatmap.Expand(rs.Attributes, "availability_zones").([]interface{})
|
v = flatmap.Expand(rs.Attributes, "availability_zones").([]interface{})
|
||||||
zones := expandStringList(v)
|
zones := expandStringList(v)
|
||||||
|
@ -43,7 +46,7 @@ func resource_aws_elb_create(
|
||||||
|
|
||||||
log.Printf("[DEBUG] ELB create configuration: %#v", elbOpts)
|
log.Printf("[DEBUG] ELB create configuration: %#v", elbOpts)
|
||||||
|
|
||||||
_, err := elbconn.CreateLoadBalancer(elbOpts)
|
_, err = elbconn.CreateLoadBalancer(elbOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error creating ELB: %s", err)
|
return nil, fmt.Errorf("Error creating ELB: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,10 @@ func resource_aws_security_group_create(
|
||||||
ingressRules := []ec2.IPPerm{}
|
ingressRules := []ec2.IPPerm{}
|
||||||
v, ok := flatmap.Expand(rs.Attributes, "ingress").([]interface{})
|
v, ok := flatmap.Expand(rs.Attributes, "ingress").([]interface{})
|
||||||
if ok {
|
if ok {
|
||||||
ingressRules = expandIPPerms(v)
|
ingressRules, err = expandIPPerms(v)
|
||||||
|
if err != nil {
|
||||||
|
return rs, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ingressRules) > 0 {
|
if len(ingressRules) > 0 {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package aws
|
package aws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mitchellh/goamz/autoscaling"
|
"github.com/mitchellh/goamz/autoscaling"
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
|
|
||||||
// Takes the result of flatmap.Expand for an array of listeners and
|
// Takes the result of flatmap.Expand for an array of listeners and
|
||||||
// returns ELB API compatible objects
|
// returns ELB API compatible objects
|
||||||
func expandListeners(configured []interface{}) []elb.Listener {
|
func expandListeners(configured []interface{}) ([]elb.Listener, error) {
|
||||||
listeners := make([]elb.Listener, 0, len(configured))
|
listeners := make([]elb.Listener, 0, len(configured))
|
||||||
|
|
||||||
// Loop over our configured listeners and create
|
// Loop over our configured listeners and create
|
||||||
|
@ -18,22 +19,29 @@ func expandListeners(configured []interface{}) []elb.Listener {
|
||||||
for _, listener := range configured {
|
for _, listener := range configured {
|
||||||
newL := listener.(map[string]interface{})
|
newL := listener.(map[string]interface{})
|
||||||
|
|
||||||
|
instancePort, err := strconv.ParseInt(newL["instance_port"].(string), 0, 0)
|
||||||
|
lbPort, err := strconv.ParseInt(newL["lb_port"].(string), 0, 0)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
l := elb.Listener{
|
l := elb.Listener{
|
||||||
InstancePort: int64(newL["instance_port"].(int)),
|
InstancePort: instancePort,
|
||||||
InstanceProtocol: newL["instance_protocol"].(string),
|
InstanceProtocol: newL["instance_protocol"].(string),
|
||||||
LoadBalancerPort: int64(newL["lb_port"].(int)),
|
LoadBalancerPort: lbPort,
|
||||||
Protocol: newL["lb_protocol"].(string),
|
Protocol: newL["lb_protocol"].(string),
|
||||||
}
|
}
|
||||||
|
|
||||||
listeners = append(listeners, l)
|
listeners = append(listeners, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
return listeners
|
return listeners, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes the result of flatmap.Expand for an array of ingress/egress
|
// Takes the result of flatmap.Expand for an array of ingress/egress
|
||||||
// security group rules and returns EC2 API compatible objects
|
// security group rules and returns EC2 API compatible objects
|
||||||
func expandIPPerms(configured []interface{}) []ec2.IPPerm {
|
func expandIPPerms(configured []interface{}) ([]ec2.IPPerm, error) {
|
||||||
perms := make([]ec2.IPPerm, 0, len(configured))
|
perms := make([]ec2.IPPerm, 0, len(configured))
|
||||||
|
|
||||||
// Loop over our configured permissions and create
|
// Loop over our configured permissions and create
|
||||||
|
@ -54,11 +62,17 @@ func expandIPPerms(configured []interface{}) []ec2.IPPerm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fromPort, err := strconv.Atoi(newP["from_port"].(string))
|
||||||
|
toPort, err := strconv.Atoi(newP["to_port"].(string))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Create the permission objet
|
// Create the permission objet
|
||||||
p := ec2.IPPerm{
|
p := ec2.IPPerm{
|
||||||
Protocol: newP["protocol"].(string),
|
Protocol: newP["protocol"].(string),
|
||||||
FromPort: newP["from_port"].(int),
|
FromPort: fromPort,
|
||||||
ToPort: newP["to_port"].(int),
|
ToPort: toPort,
|
||||||
SourceIPs: expandStringList(newP["cidr_blocks"].([]interface{})),
|
SourceIPs: expandStringList(newP["cidr_blocks"].([]interface{})),
|
||||||
SourceGroups: expandedGroups,
|
SourceGroups: expandedGroups,
|
||||||
}
|
}
|
||||||
|
@ -66,7 +80,7 @@ func expandIPPerms(configured []interface{}) []ec2.IPPerm {
|
||||||
perms = append(perms, p)
|
perms = append(perms, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
return perms
|
return perms, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flattens an array of ipPerms into a list of primitives that
|
// Flattens an array of ipPerms into a list of primitives that
|
||||||
|
|
|
@ -33,7 +33,11 @@ func testConf() map[string]string {
|
||||||
|
|
||||||
func Test_expandIPPerms(t *testing.T) {
|
func Test_expandIPPerms(t *testing.T) {
|
||||||
expanded := flatmap.Expand(testConf(), "ingress").([]interface{})
|
expanded := flatmap.Expand(testConf(), "ingress").([]interface{})
|
||||||
perms := expandIPPerms(expanded)
|
perms, err := expandIPPerms(expanded)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("bad: %#v", err)
|
||||||
|
}
|
||||||
expected := ec2.IPPerm{
|
expected := ec2.IPPerm{
|
||||||
Protocol: "icmp",
|
Protocol: "icmp",
|
||||||
FromPort: 1,
|
FromPort: 1,
|
||||||
|
@ -118,7 +122,11 @@ func Test_flattenIPPerms(t *testing.T) {
|
||||||
|
|
||||||
func Test_expandListeners(t *testing.T) {
|
func Test_expandListeners(t *testing.T) {
|
||||||
expanded := flatmap.Expand(testConf(), "listener").([]interface{})
|
expanded := flatmap.Expand(testConf(), "listener").([]interface{})
|
||||||
listeners := expandListeners(expanded)
|
listeners, err := expandListeners(expanded)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("bad: %#v", err)
|
||||||
|
}
|
||||||
|
|
||||||
expected := elb.Listener{
|
expected := elb.Listener{
|
||||||
InstancePort: 8000,
|
InstancePort: 8000,
|
||||||
LoadBalancerPort: 80,
|
LoadBalancerPort: 80,
|
||||||
|
|
|
@ -159,6 +159,12 @@ func resource_dnsimple_record_update_state(
|
||||||
s.Attributes["priority"] = rec.StringPrio()
|
s.Attributes["priority"] = rec.StringPrio()
|
||||||
s.Attributes["domain_id"] = rec.StringDomainId()
|
s.Attributes["domain_id"] = rec.StringDomainId()
|
||||||
|
|
||||||
|
if rec.Name == "" {
|
||||||
|
s.Attributes["hostname"] = s.Attributes["domain"]
|
||||||
|
} else {
|
||||||
|
s.Attributes["hostname"] = fmt.Sprintf("%s.%s", rec.Name, s.Attributes["domain"])
|
||||||
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
---
|
||||||
|
layout: "docs"
|
||||||
|
page_title: "Configuration Syntax"
|
||||||
|
sidebar_current: "docs-config-syntax"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Configuration Syntax
|
||||||
|
|
||||||
|
The syntax of Terraform configurations is custom. It is meant to
|
||||||
|
strike a balance between human readable and editable as well as being
|
||||||
|
machine-friendly. For machine-friendliness, Terraform can also
|
||||||
|
read JSON configurations. For general Terraform configurations,
|
||||||
|
however, we recommend using the Terraform syntax.
|
||||||
|
|
||||||
|
## Terraform Syntax
|
||||||
|
|
||||||
|
Here is an example of Terraform syntax:
|
||||||
|
|
||||||
|
```
|
||||||
|
# An AMI
|
||||||
|
variable "ami" {
|
||||||
|
description = "the AMI to use"
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A multi
|
||||||
|
line comment. */
|
||||||
|
resource "aws_instance" "web" {
|
||||||
|
ami = "${var.ami}"
|
||||||
|
count = 2
|
||||||
|
source_dest_check = false
|
||||||
|
|
||||||
|
connection {
|
||||||
|
user = "root"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Basic bullet point reference:
|
||||||
|
|
||||||
|
* Single line comments start with `#`
|
||||||
|
|
||||||
|
* Multi-line comments are wrapped with `/*` and `*/`
|
||||||
|
|
||||||
|
* Values are assigned with the syntax of `key = value` (whitespace
|
||||||
|
doesn't matter). The value can be any primitive: a string,
|
||||||
|
number, or boolean.
|
||||||
|
|
||||||
|
* Strings are in double-quotes.
|
||||||
|
|
||||||
|
* Numbers are assumed to be base 10. If you prefix a number with
|
||||||
|
`0x`, it is treated as a hexadecimal number.
|
||||||
|
|
||||||
|
* Numbers can be suffxed with `kKmMgG` for some multiple of 10.
|
||||||
|
For example: `1k` is equal to `1000`.
|
||||||
|
|
||||||
|
* Numbers can be suffxed with `[kKmMgG]b` for power of 2 multiples,
|
||||||
|
example: `1kb` is equal to `1024`.
|
||||||
|
|
||||||
|
* Boolean values: `true`, `false`, `on`, `off`, `yes`, `no`.
|
||||||
|
|
||||||
|
* Arrays of primitive types can be made by wrapping it in `[]`.
|
||||||
|
Example: `["foo", "bar", 42]`.
|
||||||
|
|
||||||
|
* Maps can be made with the `{}` syntax:
|
||||||
|
`{ "foo": "bar", "bar": "baz" }`.
|
||||||
|
|
||||||
|
In addition to the basics, the syntax supports hierarchies of sections,
|
||||||
|
such as the "resource" and "variable" in the example above. These
|
||||||
|
sections are similar to maps, but visually look better. For example,
|
||||||
|
these are nearly equivalent:
|
||||||
|
|
||||||
|
```
|
||||||
|
variable "ami" {
|
||||||
|
description = "the AMI to use"
|
||||||
|
}
|
||||||
|
|
||||||
|
# is equal to:
|
||||||
|
|
||||||
|
variable = [{
|
||||||
|
"ami": {
|
||||||
|
"description": "the AMI to use",
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
Notice that the top visually looks a lot better? By repeating multiple
|
||||||
|
`variable` sections, it adds the `variable` array. When possible, use
|
||||||
|
sections since they're visually clearer and more reasily readable.
|
||||||
|
|
||||||
|
## JSON Syntax
|
||||||
|
|
||||||
|
Terraform also supports reading JSON formatted configuration files.
|
||||||
|
The above example converted to JSON:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"variable": {
|
||||||
|
"ami": {
|
||||||
|
"description": "the AMI to use"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"resource": {
|
||||||
|
"aws_instance": {
|
||||||
|
"web": {
|
||||||
|
"ami": "${var.ami}",
|
||||||
|
"count": 2,
|
||||||
|
"source_dest_check": false,
|
||||||
|
|
||||||
|
"connection": {
|
||||||
|
"user": "root"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The conversion should be pretty straightforward and self-documented.
|
||||||
|
|
||||||
|
The downsides of JSON are less human readability and the lack of
|
||||||
|
comments. Otherwise, the two are completely interoperable.
|
Loading…
Reference in New Issue