Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: require cloud9 image_id to align with AWS breaking change #35020

Merged
merged 4 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changelog/35020.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_cloud9_environment_ec2: Add `amazonlinux-2023-x86_64` and `resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2023-x86_64` as valid values for `image_id`
```

```release-note:bug
resource/aws_cloud9_environment_ec2: `image_id` is Required
```
47 changes: 13 additions & 34 deletions internal/service/cloud9/environment_ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
Expand Down Expand Up @@ -61,15 +60,17 @@ func ResourceEnvironmentEC2() *schema.Resource {
},
"image_id": {
Type: schema.TypeString,
Optional: true,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
"amazonlinux-1-x86_64",
"amazonlinux-2-x86_64",
"amazonlinux-2023-x86_64",
"ubuntu-18.04-x86_64",
"ubuntu-22.04-x86_64",
"resolve:ssm:/aws/service/cloud9/amis/amazonlinux-1-x86_64",
"resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64",
"resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2023-x86_64",
"resolve:ssm:/aws/service/cloud9/amis/ubuntu-18.04-x86_64",
"resolve:ssm:/aws/service/cloud9/amis/ubuntu-22.04-x86_64",
}, false),
Expand Down Expand Up @@ -116,6 +117,7 @@ func resourceEnvironmentEC2Create(ctx context.Context, d *schema.ResourceData, m
input := &cloud9.CreateEnvironmentEC2Input{
ClientRequestToken: aws.String(id.UniqueId()),
ConnectionType: aws.String(d.Get("connection_type").(string)),
ImageId: aws.String(d.Get("image_id").(string)),
InstanceType: aws.String(d.Get("instance_type").(string)),
Name: aws.String(name),
Tags: getTagsIn(ctx),
Expand All @@ -124,50 +126,30 @@ func resourceEnvironmentEC2Create(ctx context.Context, d *schema.ResourceData, m
if v, ok := d.GetOk("automatic_stop_time_minutes"); ok {
input.AutomaticStopTimeMinutes = aws.Int64(int64(v.(int)))
}

if v, ok := d.GetOk("description"); ok {
input.Description = aws.String(v.(string))
}
if v, ok := d.GetOk("image_id"); ok {
input.ImageId = aws.String(v.(string))
}

if v, ok := d.GetOk("owner_arn"); ok {
input.OwnerArn = aws.String(v.(string))
}

if v, ok := d.GetOk("subnet_id"); ok {
input.SubnetId = aws.String(v.(string))
}

log.Printf("[INFO] Creating Cloud9 EC2 Environment: %s", input)
var output *cloud9.CreateEnvironmentEC2Output
err := retry.RetryContext(ctx, propagationTimeout, func() *retry.RetryError {
var err error
output, err = conn.CreateEnvironmentEC2WithContext(ctx, input)

if err != nil {
// NotFoundException: User arn:aws:iam::*******:user/****** does not exist.
if tfawserr.ErrMessageContains(err, cloud9.ErrCodeNotFoundException, "User") {
return retry.RetryableError(err)
}

return retry.NonRetryableError(err)
}

return nil
})

if tfresource.TimedOut(err) {
output, err = conn.CreateEnvironmentEC2WithContext(ctx, input)
}
outputRaw, err := tfresource.RetryWhenAWSErrMessageContains(ctx, propagationTimeout, func() (interface{}, error) {
return conn.CreateEnvironmentEC2WithContext(ctx, input)
}, cloud9.ErrCodeNotFoundException, "User")

if err != nil {
return sdkdiag.AppendErrorf(diags, "creating Cloud9 EC2 Environment (%s): %s", name, err)
}

d.SetId(aws.StringValue(output.EnvironmentId))
d.SetId(aws.StringValue(outputRaw.(*cloud9.CreateEnvironmentEC2Output).EnvironmentId))

_, err = waitEnvironmentReady(ctx, conn, d.Id())

if err != nil {
if _, err := waitEnvironmentReady(ctx, conn, d.Id()); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for Cloud9 EC2 Environment (%s) create: %s", d.Id(), err)
}

Expand Down Expand Up @@ -212,7 +194,6 @@ func resourceEnvironmentEC2Update(ctx context.Context, d *schema.ResourceData, m
Name: aws.String(d.Get("name").(string)),
}

log.Printf("[INFO] Updating Cloud9 EC2 Environment: %s", input)
_, err := conn.UpdateEnvironmentWithContext(ctx, &input)

if err != nil {
Expand Down Expand Up @@ -240,9 +221,7 @@ func resourceEnvironmentEC2Delete(ctx context.Context, d *schema.ResourceData, m
return sdkdiag.AppendErrorf(diags, "deleting Cloud9 EC2 Environment (%s): %s", d.Id(), err)
}

_, err = waitEnvironmentDeleted(ctx, conn, d.Id())

if err != nil {
if _, err := waitEnvironmentDeleted(ctx, conn, d.Id()); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for Cloud9 EC2 Environment (%s) delete: %s", d.Id(), err)
}

Expand Down
12 changes: 6 additions & 6 deletions internal/service/cloud9/environment_ec2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestAccCloud9EnvironmentEC2_basic(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type", "subnet_id"},
ImportStateVerifyIgnore: []string{"instance_type", "subnet_id", "image_id"},
},
},
})
Expand Down Expand Up @@ -130,7 +130,7 @@ func TestAccCloud9EnvironmentEC2_tags(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type", "subnet_id"},
ImportStateVerifyIgnore: []string{"instance_type", "subnet_id", "image_id"},
},
{
Config: testAccEnvironmentEC2Config_tags2(rName, "key1", "value1updated", "key2", "value2"),
Expand Down Expand Up @@ -186,10 +186,6 @@ func testAccCheckEnvironmentEC2Exists(ctx context.Context, n string, v *cloud9.E
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No Cloud9 Environment EC2 ID is set")
}

conn := acctest.Provider.Meta().(*conns.AWSClient).Cloud9Conn(ctx)

output, err := tfcloud9.FindEnvironmentByID(ctx, conn, rs.Primary.ID)
Expand Down Expand Up @@ -225,6 +221,7 @@ func testAccCheckEnvironmentEC2Destroy(ctx context.Context) resource.TestCheckFu

return fmt.Errorf("Cloud9 Environment EC2 %s still exists.", rs.Primary.ID)
}

return nil
}
}
Expand Down Expand Up @@ -253,6 +250,7 @@ resource "aws_cloud9_environment_ec2" "test" {
instance_type = "t2.micro"
name = %[1]q
subnet_id = aws_subnet.test[0].id
image_id = "amazonlinux-2023-x86_64"
}
`, rName))
}
Expand Down Expand Up @@ -282,6 +280,7 @@ resource "aws_cloud9_environment_ec2" "test" {
instance_type = "t2.micro"
name = %[1]q
subnet_id = aws_subnet.test[0].id
image_id = "amazonlinux-2023-x86_64"

tags = {
%[2]q = %[3]q
Expand All @@ -296,6 +295,7 @@ resource "aws_cloud9_environment_ec2" "test" {
instance_type = "t2.micro"
name = %[1]q
subnet_id = aws_subnet.test[0].id
image_id = "amazonlinux-2023-x86_64"

tags = {
%[2]q = %[3]q
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class MyConvertedCode(TerraformStack):
super().__init__(scope, name)
Cloud9EnvironmentEc2(self, "example",
instance_type="t2.micro",
name="example-env"
name="example-env",
ewbankkit marked this conversation as resolved.
Show resolved Hide resolved
image_id="amazonlinux-2023-x86_64"
)
```

Expand All @@ -51,7 +52,8 @@ class MyConvertedCode(TerraformStack):
super().__init__(scope, name)
example = Cloud9EnvironmentEc2(self, "example",
instance_type="t2.micro",
name=name
name=name,
image_id="amazonlinux-2023-x86_64"
)
DataAwsInstance(self, "cloud9_instance",
filter=[DataAwsInstanceFilter(
Expand Down Expand Up @@ -83,7 +85,8 @@ class MyConvertedCode(TerraformStack):
super().__init__(scope, name)
example = Cloud9EnvironmentEc2(self, "example",
instance_type="t2.micro",
name=name
name=name,
image_id="amazonlinux-2023-x86_64"
)
cloud9_instance = DataAwsInstance(self, "cloud9_instance",
filter=[DataAwsInstanceFilter(
Expand Down Expand Up @@ -113,10 +116,12 @@ This resource supports the following arguments:
* `image_id` - (Optional) The identifier for the Amazon Machine Image (AMI) that's used to create the EC2 instance. Valid values are
* `amazonlinux-1-x86_64`
* `amazonlinux-2-x86_64`
* `amazonlinux-2023-x86_64`
* `ubuntu-18.04-x86_64`
* `ubuntu-22.04-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/amazonlinux-1-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2023-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/ubuntu-18.04-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/ubuntu-22.04-x86_64`

Expand All @@ -133,4 +138,4 @@ This resource exports the following attributes in addition to the arguments abov
* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block).
* `type` - The type of the environment (e.g., `ssh` or `ec2`)

<!-- cache-key: cdktf-0.19.0 input-0a7b7bb4db1f7b69891ee6f0c3a4d079fd3d0b45f3d6b81be48656fbea075db1 -->
<!-- cache-key: cdktf-0.19.0 input-0a7b7bb4db1f7b69891ee6f0c3a4d079fd3d0b45f3d6b81be48656fbea075db1 -->
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MyConvertedCode extends TerraformStack {
new Cloud9EnvironmentEc2(this, "example", {
instanceType: "t2.micro",
name: "example-env",
imageId: "amazonlinux-2023-x86_64",
});
}
}
Expand Down Expand Up @@ -58,6 +59,7 @@ class MyConvertedCode extends TerraformStack {
const example = new Cloud9EnvironmentEc2(this, "example", {
instanceType: "t2.micro",
name: config.name,
imageId: "amazonlinux-2023-x86_64",
});
new DataAwsInstance(this, "cloud9_instance", {
filter: [
Expand Down Expand Up @@ -102,6 +104,7 @@ class MyConvertedCode extends TerraformStack {
const example = new Cloud9EnvironmentEc2(this, "example", {
instanceType: "t2.micro",
name: config.name,
imageId: "amazonlinux-2023-x86_64",
});
const cloud9Instance = new DataAwsInstance(this, "cloud9_instance", {
filter: [
Expand Down Expand Up @@ -135,10 +138,12 @@ This resource supports the following arguments:
* `imageId` - (Optional) The identifier for the Amazon Machine Image (AMI) that's used to create the EC2 instance. Valid values are
* `amazonlinux-1-x86_64`
* `amazonlinux-2-x86_64`
* `amazonlinux-2023-x86_64`
* `ubuntu-18.04-x86_64`
* `ubuntu-22.04-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/amazonlinux-1-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2023-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/ubuntu-18.04-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/ubuntu-22.04-x86_64`

Expand All @@ -155,4 +160,4 @@ This resource exports the following attributes in addition to the arguments abov
* `tagsAll` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block).
* `type` - The type of the environment (e.g., `ssh` or `ec2`)

<!-- cache-key: cdktf-0.19.0 input-0a7b7bb4db1f7b69891ee6f0c3a4d079fd3d0b45f3d6b81be48656fbea075db1 -->
<!-- cache-key: cdktf-0.19.0 input-0a7b7bb4db1f7b69891ee6f0c3a4d079fd3d0b45f3d6b81be48656fbea075db1 -->
14 changes: 8 additions & 6 deletions website/docs/r/cloud9_environment_ec2.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Basic usage:
resource "aws_cloud9_environment_ec2" "example" {
instance_type = "t2.micro"
name = "example-env"
image_id = "amazonlinux-2023-x86_64"
}
```

Expand Down Expand Up @@ -72,19 +73,20 @@ This resource supports the following arguments:

* `name` - (Required) The name of the environment.
* `instance_type` - (Required) The type of instance to connect to the environment, e.g., `t2.micro`.
* `automatic_stop_time_minutes` - (Optional) The number of minutes until the running instance is shut down after the environment has last been used.
* `connection_type` - (Optional) The connection type used for connecting to an Amazon EC2 environment. Valid values are `CONNECT_SSH` and `CONNECT_SSM`. For more information please refer [AWS documentation for Cloud9](https://docs.aws.amazon.com/cloud9/latest/user-guide/ec2-ssm.html).
* `description` - (Optional) The description of the environment.
* `image_id` - (Optional) The identifier for the Amazon Machine Image (AMI) that's used to create the EC2 instance. Valid values are
* `image_id` - (Required) The identifier for the Amazon Machine Image (AMI) that's used to create the EC2 instance. Valid values are
* `amazonlinux-1-x86_64`
* `amazonlinux-2-x86_64`
* `amazonlinux-2023-x86_64`
* `ubuntu-18.04-x86_64`
* `ubuntu-22.04-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/amazonlinux-1-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2023-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/ubuntu-18.04-x86_64`
* `resolve:ssm:/aws/service/cloud9/amis/ubuntu-22.04-x86_64`

* `automatic_stop_time_minutes` - (Optional) The number of minutes until the running instance is shut down after the environment has last been used.
* `connection_type` - (Optional) The connection type used for connecting to an Amazon EC2 environment. Valid values are `CONNECT_SSH` and `CONNECT_SSM`. For more information please refer [AWS documentation for Cloud9](https://docs.aws.amazon.com/cloud9/latest/user-guide/ec2-ssm.html).
* `description` - (Optional) The description of the environment.
* `owner_arn` - (Optional) The ARN of the environment owner. This can be ARN of any AWS IAM principal. Defaults to the environment's creator.
* `subnet_id` - (Optional) The ID of the subnet in Amazon VPC that AWS Cloud9 will use to communicate with the Amazon EC2 instance.
* `tags` - (Optional) Key-value map of resource tags. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
Expand All @@ -96,4 +98,4 @@ This resource exports the following attributes in addition to the arguments abov
* `id` - The ID of the environment.
* `arn` - The ARN of the environment.
* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block).
* `type` - The type of the environment (e.g., `ssh` or `ec2`)
* `type` - The type of the environment (e.g., `ssh` or `ec2`).
Loading