-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Feat: AWS Resilience Hub App resource #44076
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
base: main
Are you sure you want to change the base?
Conversation
Community GuidelinesThis comment is added to every new Pull Request to provide quick reference to how the Terraform AWS Provider is maintained. Please review the information below, and thank you for contributing to the community that keeps the provider thriving! 🚀 Voting for Prioritization
Pull Request Authors
|
✅ Thank you for correcting the previously detected issues! The maintainers appreciate your efforts to make the review process as smooth as possible. |
5d10a44
to
8edc9ba
Compare
44669c6
to
9d560bf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few specific comments, but broadly the current implementation seems like it should be split into multiple resources. It might be worth completing a service design that describes potential resources, which APIs they map to, and the expected interaction between them.
_, err = conn.PutDraftAppVersionTemplate(ctx, templateInput) | ||
if err != nil { | ||
resp.Diagnostics.AddError( | ||
create.ProblemStandardMessage(names.ResilienceHub, create.ErrActionCreating, ResNameApp, name, err), | ||
err.Error(), | ||
) | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a separate resource, distinct from the parent app?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that could make sense. I intended the TF resource to be similar to CloudFormation, which has a singular App and combines these. But I could see it also making sense to split them out. You had mentioned that this feature might need a service design document? If so, I can wait to split them out until that happens. Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some more clarity as a comment for why I've combined these as a single resource, hope that makes more sense.
_, err := conn.ImportResourcesToDraftAppVersion(ctx, importInput) | ||
if err != nil { | ||
resp.Diagnostics.AddError( | ||
create.ProblemStandardMessage(names.ResilienceHub, create.ErrActionCreating, ResNameApp, name, err), | ||
err.Error(), | ||
) | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The resource import workflow could also potentially be it's own resource.
This commit adds a gap in the AWS Resilience Hub service: an app resource. It includes the schema required to define and manage that app.
Ensure app schema uses autoflex
9d560bf
to
08da7d2
Compare
AWS ResilienceHub App Resource - Terraform Schema ProposalOverviewThis proposal introduces the Key Design Decision: Matching CloudFormation's Combined ApproachCloudFormation's
This Terraform implementation replicates this exact functionality but provides it in a more structured, type-safe way:
This approach maintains full feature parity with CloudFormation while providing better Terraform ergonomics. Rather than defining a single string of loose json, this proposal allows users to craft the template as HCL. Schema StructureBasic Resource Configurationresource "aws_resiliencehub_app" "example" {
name = "my-resilience-app"
description = "Example resilience hub application"
app_assessment_schedule = "Daily"
resiliency_policy_arn = aws_resiliencehub_resiliency_policy.example.arn
tags = {
Environment = "production"
Team = "platform"
}
} App Template Block (Replaces CloudFormation's AppTemplateBody JSON)The app_template {
version = "2.0"
# Define application resources
resource {
name = "lambda-function"
type = "AWS::Lambda::Function"
logical_resource_id {
identifier = "MyLambdaFunction"
logical_stack_name = "my-stack"
}
}
# Define application components
app_component {
name = "compute-tier"
type = "AWS::ResilienceHub::ComputeAppComponent"
resource_names = ["lambda-function"]
}
} Resource Mapping Block (Replaces CloudFormation's ResourceMappings Array)The resource_mapping {
mapping_type = "Terraform"
resource_name = "lambda-function"
terraform_source_name = "my-terraform-source"
physical_resource_id {
type = "Native"
identifier = "s3://my-terraform-bucket/terraform.tfstate"
}
} CloudFormation vs Terraform ComparisonCloudFormation (JSON string approach):Type: AWS::ResilienceHub::App
Properties:
Name: my-app
AppTemplateBody: '{"resources":[{"logicalResourceId":{"identifier":"MyLambda"},"type":"AWS::Lambda::Function","name":"lambda-function"}],"appComponents":[{"name":"compute-tier","type":"AWS::ResilienceHub::ComputeAppComponent","resourceNames":["lambda-function"]}],"version":"2.0"}'
ResourceMappings:
- ResourceName: lambda-function
MappingType: Terraform
PhysicalResourceId:
Type: Native
Identifier: s3://my-bucket/terraform.tfstate Terraform (structured approach):resource "aws_resiliencehub_app" "my_app" {
name = "my-app"
app_template {
version = "2.0"
resource {
name = "lambda-function"
type = "AWS::Lambda::Function"
logical_resource_id {
identifier = "MyLambda"
}
}
app_component {
name = "compute-tier"
type = "AWS::ResilienceHub::ComputeAppComponent"
resource_names = ["lambda-function"]
}
}
resource_mapping {
mapping_type = "Terraform"
resource_name = "lambda-function"
physical_resource_id {
type = "Native"
identifier = "s3://my-bucket/terraform.tfstate"
}
}
} Result: Same functionality, better developer experience. Complete Example: Terraform Source Integrationresource "aws_resiliencehub_app" "terraform_app" {
name = "terraform-managed-app"
description = "App with S3 Terraform state source"
app_assessment_schedule = "Daily"
app_template {
version = "2.0"
resource {
name = "lambda-function"
type = "AWS::Lambda::Function"
logical_resource_id {
identifier = "MyLambda"
terraform_source_name = "my-terraform-source"
}
}
app_component {
name = "compute-tier"
type = "AWS::ResilienceHub::ComputeAppComponent"
resource_names = ["lambda-function"]
}
}
resource_mapping {
mapping_type = "Terraform"
resource_name = "lambda-function"
terraform_source_name = "my-terraform-source"
physical_resource_id {
type = "Native"
identifier = "s3://my-terraform-bucket/terraform.tfstate"
}
}
} Schema AttributesTop-level Attributes
App Template Block
Resource Sub-block
Logical Resource ID Sub-block
App Component Sub-block
Resource Mapping Block
Physical Resource ID Sub-block
Implementation Benefits
Test Coverage ExamplesBasic App Creationresource "aws_resiliencehub_app" "test" {
name = "tf-test-app"
app_assessment_schedule = "Disabled"
app_template {
version = "2.0"
app_component {
name = "appcommon"
type = "AWS::ResilienceHub::AppCommonAppComponent"
resource_names = []
}
}
} Terraform Source Integrationresource "aws_resiliencehub_app" "test" {
name = "terraform-source-app"
description = "Test app with S3 Terraform source"
app_assessment_schedule = "Disabled"
app_template {
version = "2.0"
resource {
name = "lambda-function"
type = "AWS::Lambda::Function"
logical_resource_id {
identifier = "MyLambda"
terraform_source_name = "my-terraform-source"
}
}
app_component {
name = "compute-tier"
type = "AWS::ResilienceHub::ComputeAppComponent"
resource_names = ["lambda-function"]
}
}
resource_mapping {
mapping_type = "Terraform"
resource_name = "lambda-function"
terraform_source_name = "my-terraform-source"
physical_resource_id {
type = "Native"
identifier = "s3://my-terraform-bucket/terraform.tfstate"
}
}
} Complete Multi-Component Appresource "aws_resiliencehub_app" "test" {
name = "complete-app"
description = "Complete test app"
app_assessment_schedule = "Daily"
app_template {
version = "2.0"
resource {
name = "lambda-function"
type = "AWS::Lambda::Function"
logical_resource_id {
identifier = "MyLambda"
logical_stack_name = "my-stack"
}
}
resource {
name = "database"
type = "AWS::RDS::DBInstance"
logical_resource_id {
identifier = "MyDatabase"
logical_stack_name = "my-stack"
}
}
app_component {
name = "compute-tier"
type = "AWS::ResilienceHub::ComputeAppComponent"
resource_names = ["lambda-function"]
}
app_component {
name = "database-tier"
type = "AWS::ResilienceHub::DatabaseAppComponent"
resource_names = ["database"]
}
}
tags = {
Environment = "test"
Purpose = "testing"
}
} |
Hello AWS TF Provider maintainers! I have another pull request for you. This PR fills a gap in the existing Resilience Hub service for the App resource, which has not yet been covered by the official AWS provider.
Rollback Plan
If a change needs to be reverted, we will publish an updated version of the library.
Changes to Security Controls
Are there any changes to security controls (access controls, encryption, logging) in this pull request? If so, explain.
N/A
Description
This commit adds a gap in the AWS Resilience Hub service: an app resource. It includes the schema required to define and manage that app. It is a simple resource with only a few fields. This commit does add more unit and acceptance tests to verify the change.
Relations
Closes #35803.
Closes #25123.
References
Output from Acceptance Testing