providers/aws: Opsworks permission resource (#6304)
* add opsworks permission resource * add docs * remove permission from state if the permission object could not be found * remove nil validate function. validation is done in schema.Resource. * add id to the list of exported values * renge over permission to check that we have found got the correct one * removed comment * removed set id * fix unknown region us-east-1c * add user_profile resource * add docs * add default value
This commit is contained in:
parent
28d10d6eb5
commit
ecb4b5aada
|
@ -234,6 +234,8 @@ func Provider() terraform.ResourceProvider {
|
|||
"aws_opsworks_ganglia_layer": resourceAwsOpsworksGangliaLayer(),
|
||||
"aws_opsworks_custom_layer": resourceAwsOpsworksCustomLayer(),
|
||||
"aws_opsworks_instance": resourceAwsOpsworksInstance(),
|
||||
"aws_opsworks_user_profile": resourceAwsOpsworksUserProfile(),
|
||||
"aws_opsworks_permission": resourceAwsOpsworksPermission(),
|
||||
"aws_placement_group": resourceAwsPlacementGroup(),
|
||||
"aws_proxy_protocol_policy": resourceAwsProxyProtocolPolicy(),
|
||||
"aws_rds_cluster": resourceAwsRDSCluster(),
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"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 resourceAwsOpsworksPermission() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsOpsworksPermissionCreate,
|
||||
Update: resourceAwsOpsworksPermissionCreate,
|
||||
Delete: resourceAwsOpsworksPermissionDelete,
|
||||
Read: resourceAwsOpsworksPermissionRead,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"allow_ssh": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
},
|
||||
"allow_sudo": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
},
|
||||
"user_arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
// one of deny, show, deploy, manage, iam_only
|
||||
"level": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
||||
value := v.(string)
|
||||
|
||||
expected := [5]string{"deny", "show", "deploy", "manage", "iam_only"}
|
||||
|
||||
found := false
|
||||
for _, b := range expected {
|
||||
if b == value {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
errors = append(errors, fmt.Errorf(
|
||||
"%q has to be one of [deny, show, deploy, manage, iam_only]", k))
|
||||
}
|
||||
return
|
||||
},
|
||||
},
|
||||
"stack_id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksPermissionDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksPermissionRead(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*AWSClient).opsworksconn
|
||||
|
||||
req := &opsworks.DescribePermissionsInput{
|
||||
IamUserArn: aws.String(d.Get("user_arn").(string)),
|
||||
StackId: aws.String(d.Get("stack_id").(string)),
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Reading OpsWorks prermissions for: %s on stack: %s", d.Get("user_arn"), d.Get("stack_id"))
|
||||
|
||||
resp, err := client.DescribePermissions(req)
|
||||
if err != nil {
|
||||
if awserr, ok := err.(awserr.Error); ok {
|
||||
if awserr.Code() == "ResourceNotFoundException" {
|
||||
log.Printf("[INFO] Permission not found")
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
found := false
|
||||
id := ""
|
||||
for _, permission := range resp.Permissions {
|
||||
id = *permission.IamUserArn + *permission.StackId
|
||||
|
||||
if d.Get("user_arn").(string)+d.Get("stack_id").(string) == id {
|
||||
found = true
|
||||
d.SetId(id)
|
||||
d.Set("id", id)
|
||||
d.Set("allow_ssh", permission.AllowSudo)
|
||||
d.Set("allow_sodo", permission.AllowSudo)
|
||||
d.Set("user_arn", permission.IamUserArn)
|
||||
d.Set("stack_id", permission.StackId)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if false == found {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] The correct permission could not be found for: %s on stack: %s", d.Get("user_arn"), d.Get("stack_id"))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksPermissionCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*AWSClient).opsworksconn
|
||||
|
||||
req := &opsworks.SetPermissionInput{
|
||||
AllowSudo: aws.Bool(d.Get("allow_sudo").(bool)),
|
||||
AllowSsh: aws.Bool(d.Get("allow_ssh").(bool)),
|
||||
IamUserArn: aws.String(d.Get("user_arn").(string)),
|
||||
StackId: aws.String(d.Get("stack_id").(string)),
|
||||
}
|
||||
|
||||
var resp *opsworks.SetPermissionOutput
|
||||
err := resource.Retry(2*time.Minute, func() *resource.RetryError {
|
||||
var cerr error
|
||||
resp, cerr = client.SetPermission(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
|
||||
}
|
||||
|
||||
return resourceAwsOpsworksPermissionRead(d, meta)
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccAWSOpsworksPermission(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAwsOpsworksPermissionCreate,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_permission.tf-acc-perm", "allow_ssh", "true",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_permission.tf-acc-perm", "allow_sudo", "true",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_permission.tf-acc-perm", "level", "iam_only",
|
||||
),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
var testAccAwsOpsworksPermissionCreate = testAccAwsOpsworksUserProfileCreate + `
|
||||
resource "aws_opsworks_permission" "tf-acc-perm" {
|
||||
stack_id = "${aws_opsworks_stack.tf-acc.id}"
|
||||
|
||||
allow_ssh = true
|
||||
allow_sudo = true
|
||||
user_arn = "${aws_opsworks_user_profile.user.user_arn}"
|
||||
level = "iam_only"
|
||||
}
|
||||
`
|
|
@ -26,7 +26,7 @@ func TestAccAWSOpsworksStackNoVpc(t *testing.T) {
|
|||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAwsOpsworksStackConfigNoVpcCreate(stackName),
|
||||
Check: testAccAwsOpsworksStackCheckResourceAttrsCreate("us-east-1c", stackName),
|
||||
Check: testAccAwsOpsworksStackCheckResourceAttrsCreate("us-east-1a", stackName),
|
||||
},
|
||||
// resource.TestStep{
|
||||
// Config: testAccAWSOpsworksStackConfigNoVpcUpdate(stackName),
|
||||
|
@ -236,7 +236,7 @@ resource "aws_opsworks_stack" "tf-acc" {
|
|||
region = "us-east-1"
|
||||
service_role_arn = "${aws_iam_role.opsworks_service.arn}"
|
||||
default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
|
||||
default_availability_zone = "us-east-1c"
|
||||
default_availability_zone = "us-east-1a"
|
||||
default_os = "Amazon Linux 2014.09"
|
||||
default_root_device_type = "ebs"
|
||||
custom_json = "{\"key\": \"value\"}"
|
||||
|
@ -317,7 +317,7 @@ resource "aws_opsworks_stack" "tf-acc" {
|
|||
region = "us-east-1"
|
||||
service_role_arn = "${aws_iam_role.opsworks_service.arn}"
|
||||
default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
|
||||
default_availability_zone = "us-east-1c"
|
||||
default_availability_zone = "us-east-1a"
|
||||
default_os = "Amazon Linux 2014.09"
|
||||
default_root_device_type = "ebs"
|
||||
custom_json = "{\"key\": \"value\"}"
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/opsworks"
|
||||
)
|
||||
|
||||
func resourceAwsOpsworksUserProfile() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsOpsworksUserProfileCreate,
|
||||
Read: resourceAwsOpsworksUserProfileRead,
|
||||
Update: resourceAwsOpsworksUserProfileUpdate,
|
||||
Delete: resourceAwsOpsworksUserProfileDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"user_arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"allow_self_management": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
},
|
||||
|
||||
"ssh_username": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"ssh_public_key": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksUserProfileRead(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*AWSClient).opsworksconn
|
||||
|
||||
req := &opsworks.DescribeUserProfilesInput{
|
||||
IamUserArns: []*string{
|
||||
aws.String(d.Id()),
|
||||
},
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Reading OpsWorks user profile: %s", d.Id())
|
||||
|
||||
resp, err := client.DescribeUserProfiles(req)
|
||||
if err != nil {
|
||||
if awserr, ok := err.(awserr.Error); ok {
|
||||
if awserr.Code() == "ResourceNotFoundException" {
|
||||
log.Printf("[DEBUG] OpsWorks user profile (%s) not found", d.Id())
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
for _, profile := range resp.UserProfiles {
|
||||
d.Set("allow_self_management", profile.AllowSelfManagement)
|
||||
d.Set("user_arn", profile.IamUserArn)
|
||||
d.Set("ssh_public_key", profile.SshPublicKey)
|
||||
d.Set("ssh_username", profile.SshUsername)
|
||||
break
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksUserProfileCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*AWSClient).opsworksconn
|
||||
|
||||
req := &opsworks.CreateUserProfileInput{
|
||||
AllowSelfManagement: aws.Bool(d.Get("allow_self_management").(bool)),
|
||||
IamUserArn: aws.String(d.Get("user_arn").(string)),
|
||||
SshPublicKey: aws.String(d.Get("ssh_public_key").(string)),
|
||||
SshUsername: aws.String(d.Get("ssh_username").(string)),
|
||||
}
|
||||
|
||||
resp, err := client.CreateUserProfile(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(*resp.IamUserArn)
|
||||
|
||||
return resourceAwsOpsworksUserProfileUpdate(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksUserProfileUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*AWSClient).opsworksconn
|
||||
|
||||
req := &opsworks.UpdateUserProfileInput{
|
||||
AllowSelfManagement: aws.Bool(d.Get("allow_self_management").(bool)),
|
||||
IamUserArn: aws.String(d.Get("user_arn").(string)),
|
||||
SshPublicKey: aws.String(d.Get("ssh_public_key").(string)),
|
||||
SshUsername: aws.String(d.Get("ssh_username").(string)),
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Updating OpsWorks user profile: %s", req)
|
||||
|
||||
_, err := client.UpdateUserProfile(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceAwsOpsworksUserProfileRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsOpsworksUserProfileDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*AWSClient).opsworksconn
|
||||
|
||||
req := &opsworks.DeleteUserProfileInput{
|
||||
IamUserArn: aws.String(d.Id()),
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Deleting OpsWorks user profile: %s", d.Id())
|
||||
|
||||
_, err := client.DeleteUserProfile(req)
|
||||
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccAWSOpsworksUserProfile(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAwsOpsworksUserProfileCreate,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_user_profile.user", "ssh_public_key", "",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_user_profile.user", "ssh_username", "test-user",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_opsworks_user_profile.user", "allow_self_management", "false",
|
||||
),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
var testAccAwsOpsworksUserProfileCreate = testAccAWSUserConfig + testAccAwsOpsworksStackConfigNoVpcCreate("tf-ops-acc-user-profile") + `
|
||||
resource "aws_opsworks_user_profile" "user" {
|
||||
user_arn = "${aws_iam_user.user.arn}"
|
||||
ssh_username = "${aws_iam_user.user.name}"
|
||||
}
|
||||
`
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: aws_opsworks_permission"
|
||||
sidebar_current: "docs-aws-resource-opsworks-permission"
|
||||
description: |-
|
||||
Provides an OpsWorks permission resource.
|
||||
-------------------------------------------
|
||||
|
||||
# aws\_opsworks\_permission
|
||||
|
||||
Provides an OpsWorks permission resource.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "aws_opsworks_permission" "my_stack_permission" {
|
||||
allow_ssh = true
|
||||
allow_sudo = true
|
||||
level = "iam_only"
|
||||
user_arn = "${aws_iam_user.user.arn}"
|
||||
stack_id = "${aws_opsworks_stack.stack.id}"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `allow_ssh` - (Optional) Whethe the user is allowed to use SSH to communicate with the instance
|
||||
* `allow_sudo` - (Optional) Whethe the user is allowed to use sudo to elevate privileges
|
||||
* `user_arn` - (Required) The user's IAM ARN to set permissions for
|
||||
* `level` - (Optional) The users permission level. Mus be one of `deny`, `show`, `deploy`, `manage`, `iam_only`
|
||||
* `stack_id` - (Required) The stack to set the permissions for
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The computed id of the permission. Please note that this is only used internally to identify the permission. This value is not used in aws.
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: aws_opsworks_user_profile_"
|
||||
sidebar_current: "docs-aws-resource-opsworks-user-profile"
|
||||
description: |-
|
||||
Provides an OpsWorks User Profile resource.
|
||||
---------------------------------------------
|
||||
|
||||
# aws\_opsworks\_user\_profile
|
||||
|
||||
Provides an OpsWorks User Profile resource.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "aws_opsworks_user_profile" "my_profile" {
|
||||
user_arn = "${aws_iam_user.user.arn}"
|
||||
ssh_username = "my_user"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `user_arn` - (Required) The user's IAM ARN
|
||||
* `allow_self_management` - (Optional) Whether users can specify their own SSH public key through the My Settings page
|
||||
* `ssh_username` - (Required) The ssh username, with witch this user wants to log in
|
||||
* `ssh_public_key` - (Optional) The users public key
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - Same value as `user_arn`
|
Loading…
Reference in New Issue