-
Notifications
You must be signed in to change notification settings - Fork 467
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
Added solution.md with images for Day-03: Terraform Configuration for AWS EC2 Instance with Provisioners, State Management, and Lifecycle Configuration #23
base: main
Are you sure you want to change the base?
Conversation
Warning Rate limit exceeded@Amitabh-DevOps has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 11 minutes and 27 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. WalkthroughThe changes introduce several new Terraform configuration files and guides for managing AWS resources. The Changes
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
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.
Actionable comments posted: 9
🧹 Outside diff range and nitpick comments (5)
day03/ec2.tf (1)
21-22
: Avoid usingaws_default_vpc
; consider creating a custom VPC insteadUsing the
aws_default_vpc
resource is not recommended because the default VPC can be modified outside of Terraform, leading to configuration drift or unintended changes. It's better to define a custom VPC for better control over your networking environment.day02/solution.md (1)
80-80
: Remove trailing punctuation in headingThe heading on line 80 has a trailing colon, which is against Markdown style guidelines and may cause rendering issues.
Apply this diff to fix the issue:
-## Example of a `main.tf` file: +## Example of a `main.tf` file🧰 Tools
🪛 Markdownlint (0.35.0)
80-80: Punctuation: ':'
Trailing punctuation in heading(MD026, no-trailing-punctuation)
day03/solution.md (3)
139-145
: Document lifecycle configuration security implicationsWhile the lifecycle configuration is technically correct, consider adding comments explaining the security implications of each setting, especially for production environments.
Consider this enhanced version with documentation:
lifecycle { - create_before_destroy = true # Create the new instance before destroying the old one - prevent_destroy = false # Allow the resource to be destroyed - ignore_changes = [tags] # Ignore changes to the tags + # Ensures zero-downtime deployments by creating new instance before destroying old one + create_before_destroy = true + + # WARNING: Setting this to false allows destruction of the resource + # Consider setting to true for production environments to prevent accidental deletion + prevent_destroy = false + + # Prevents Terraform from attempting to reconcile external tag changes + # Useful when tags are managed by other tools or teams + ignore_changes = [tags] }
188-215
: Enhance Terraform commands section with production best practicesThe commands section should include additional important commands and flags for production use.
Consider adding these essential commands:
# Existing commands... + +# Workspace Management +terraform workspace new production # Create a new workspace +terraform workspace select production # Switch to a workspace + +# State Management +terraform state list # List resources in state +terraform state show # Show state for a resource + +# Plan with detailed exit codes +terraform plan -detailed-exitcode + +# Apply with backup +terraform apply -backup=tfstate.backup + +# Import existing resources +terraform import aws_instance.example i-1234567890abcdef0
1-216
: Improve documentation structure and add security considerationsThe documentation would benefit from:
- Consistent heading hierarchy
- A dedicated security considerations section
- Prerequisites section with required permissions
Consider adding these sections before the tasks:
## Prerequisites - AWS IAM permissions required: - EC2:* - SecurityGroup:* - KeyPair:* ## Security Considerations - Use AWS KMS for key management - Implement proper security group rules - Follow the principle of least privilege - Consider using AWS Systems Manager Session Manager instead of SSH🧰 Tools
🪛 LanguageTool
[uncategorized] ~55-~55: Did you mean “applies” or “applied”?
Context: ...](images/task2.3.2.png) - Terraform apply : ![task2.4.1](images/task2.4.1.p...(NNP_VBP_TO_VBZ)
[uncategorized] ~104-~104: Did you mean “applies” or “applied”?
Context: ...--auto-approve ``` - Terraform apply images: ![task3.3.1](images/t...(NNP_VBP_TO_VBZ)
[uncategorized] ~126-~126: Did you mean “destroys” or “destroyed”?
Context: ...ypeyes
to proceed). - Terraform destroy images : ![task3.2.1](images/...(NNP_VBP_TO_VBZ)
[uncategorized] ~152-~152: Loose punctuation mark.
Context: ...) -create_before_destroy = true
: - This ensures that Terraform create...(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~155-~155: Loose punctuation mark.
Context: ...stance. -prevent_destroy = false
: - This allows the resource to be des...(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~167-~167: Loose punctuation mark.
Context: ...) -ignore_changes = [tags]
: - This instructs Terraform to ignore...(UNLIKELY_OPENING_PUNCTUATION)
🪛 Markdownlint (0.35.0)
4-4: Expected: h2; Actual: h3
Heading levels should only increment by one level at a time(MD001, heading-increment)
104-104: Expected: 2; Actual: 4
Unordered list indentation(MD007, ul-indent)
113-113: Expected: 2; Actual: 4
Unordered list indentation(MD007, ul-indent)
126-126: Expected: 2; Actual: 4
Unordered list indentation(MD007, ul-indent)
173-173: Punctuation: ':'
Trailing punctuation in heading(MD026, no-trailing-punctuation)
186-186: Punctuation: ':'
Trailing punctuation in heading(MD026, no-trailing-punctuation)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (21)
day02/images/task3.1.png
is excluded by!**/*.png
day02/images/task3.2.png
is excluded by!**/*.png
day02/images/task3.3.png
is excluded by!**/*.png
day03/images/task2.1.png
is excluded by!**/*.png
day03/images/task2.2.png
is excluded by!**/*.png
day03/images/task2.3.1.png
is excluded by!**/*.png
day03/images/task2.3.2.png
is excluded by!**/*.png
day03/images/task2.4.1.png
is excluded by!**/*.png
day03/images/task2.4.2.png
is excluded by!**/*.png
day03/images/task2.5.png
is excluded by!**/*.png
day03/images/task3.1.png
is excluded by!**/*.png
day03/images/task3.2.1.png
is excluded by!**/*.png
day03/images/task3.2.2.png
is excluded by!**/*.png
day03/images/task3.3.1.png
is excluded by!**/*.png
day03/images/task3.3.2.png
is excluded by!**/*.png
day03/images/task3.3.3.png
is excluded by!**/*.png
day03/images/task3.3.4.png
is excluded by!**/*.png
day03/images/task4.1.png
is excluded by!**/*.png
day03/images/task4.2.1.png
is excluded by!**/*.png
day03/images/task4.2.2.png
is excluded by!**/*.png
day03/images/task4.2.3.png
is excluded by!**/*.png
📒 Files selected for processing (10)
day01/solution.md
(1 hunks)day02/main.tf
(1 hunks)day02/solution.md
(1 hunks)day02/variable.tf
(1 hunks)day03/ec2.tf
(1 hunks)day03/main.tf
(1 hunks)day03/output.tf
(1 hunks)day03/solution.md
(1 hunks)day03/terraform.tf
(1 hunks)day03/variable.tf
(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- day03/main.tf
- day03/output.tf
- day03/terraform.tf
🧰 Additional context used
🪛 Markdownlint (0.35.0)
day02/solution.md
80-80: Punctuation: ':'
Trailing punctuation in heading
(MD026, no-trailing-punctuation)
day01/solution.md
3-3: Expected: h2; Actual: h3
Heading levels should only increment by one level at a time
(MD001, heading-increment)
day03/solution.md
4-4: Expected: h2; Actual: h3
Heading levels should only increment by one level at a time
(MD001, heading-increment)
104-104: Expected: 2; Actual: 4
Unordered list indentation
(MD007, ul-indent)
113-113: Expected: 2; Actual: 4
Unordered list indentation
(MD007, ul-indent)
126-126: Expected: 2; Actual: 4
Unordered list indentation
(MD007, ul-indent)
173-173: Punctuation: ':'
Trailing punctuation in heading
(MD026, no-trailing-punctuation)
186-186: Punctuation: ':'
Trailing punctuation in heading
(MD026, no-trailing-punctuation)
🪛 checkov (3.2.312)
day03/ec2.tf
[HIGH] 67-106: Ensure Instance Metadata Service Version 1 is not enabled
(CKV_AWS_79)
🪛 LanguageTool
day03/solution.md
[uncategorized] ~55-~55: Did you mean “applies” or “applied”?
Context: ...](images/task2.3.2.png) - Terraform apply : ![task2.4.1](images/task2.4.1.p...
(NNP_VBP_TO_VBZ)
[uncategorized] ~104-~104: Did you mean “applies” or “applied”?
Context: ...--auto-approve ``` - Terraform apply images: ![task3.3.1](images/t...
(NNP_VBP_TO_VBZ)
[uncategorized] ~126-~126: Did you mean “destroys” or “destroyed”?
Context: ...ype yes
to proceed). - Terraform destroy images : ![task3.2.1](images/...
(NNP_VBP_TO_VBZ)
[uncategorized] ~152-~152: Loose punctuation mark.
Context: ...) - create_before_destroy = true
: - This ensures that Terraform create...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~155-~155: Loose punctuation mark.
Context: ...stance. - prevent_destroy = false
: - This allows the resource to be des...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~167-~167: Loose punctuation mark.
Context: ...) - ignore_changes = [tags]
: - This instructs Terraform to ignore...
(UNLIKELY_OPENING_PUNCTUATION)
🔇 Additional comments (2)
day02/variable.tf (1)
1-5
: Variable definition looks good
The bucket_name
variable is well-defined with a clear description, type, and default value. This allows for flexible configuration of the S3 bucket name.
day02/main.tf (1)
1-13
: Provider configuration is appropriate
The AWS provider is correctly specified with the required version and source. This ensures compatibility and stability for your Terraform configuration.
ingress { | ||
description = "Allow access to SSH port 22" | ||
from_port = 22 | ||
to_port = 22 | ||
protocol = var.ssh_protocol | ||
cidr_blocks = [var.ssh_cidr] | ||
} |
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.
Restrict SSH access to trusted IP addresses
Allowing SSH access from 0.0.0.0/0
exposes your instance to the internet, posing a significant security risk. It's recommended to restrict SSH access to specific IP addresses or ranges that are trusted.
Apply this diff to restrict SSH access:
ingress {
description = "Allow access to SSH port 22"
from_port = 22
to_port = 22
protocol = var.ssh_protocol
- cidr_blocks = [var.ssh_cidr]
+ cidr_blocks = ["your-trusted-ip/32"]
}
Replace "your-trusted-ip/32"
with your actual IP address or network range.
Committable suggestion skipped: line range outside the PR's diff.
provisioner "remote-exec" { | ||
inline = [ | ||
"sudo apt update", | ||
"sudo apt install -y nginx", | ||
"sudo systemctl start nginx", | ||
"sudo systemctl enable nginx" | ||
] | ||
|
||
# Use the private key for SSH authentication | ||
connection { | ||
type = "ssh" | ||
user = "ubuntu" | ||
private_key = file(var.aws_private_key_pair_name) | ||
host = self.public_ip | ||
} | ||
} |
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.
🛠️ Refactor suggestion
Avoid using provisioners; consider using user data instead
Using provisioners can lead to unpredictable behavior and should be used as a last resort. Instead, consider using the user_data
attribute to run scripts on instance launch. This approach is more reliable and integrates better with Terraform's lifecycle.
Apply this diff to replace the provisioner with user_data
:
resource "aws_instance" "my_instance" {
...
- # Provisioner to install nginx on the instance after it's created
- provisioner "remote-exec" {
- inline = [
- "sudo apt update",
- "sudo apt install -y nginx",
- "sudo systemctl start nginx",
- "sudo systemctl enable nginx"
- ]
-
- # Use the private key for SSH authentication
- connection {
- type = "ssh"
- user = "ubuntu"
- private_key = file(var.aws_private_key_pair_name)
- host = self.public_ip
- }
- }
+ # Use user_data to install and start nginx
+ user_data = <<-EOF
+ #!/bin/bash
+ sudo apt update
+ sudo apt install -y nginx
+ sudo systemctl start nginx
+ sudo systemctl enable nginx
+ EOF
# Lifecycle management configuration
lifecycle {
create_before_destroy = true # Create the new instance before destroying the old one
prevent_destroy = false # Allow the resource to be destroyed
ignore_changes = [tags] # Ignore changes to the tags
}
}
Committable suggestion skipped: line range outside the PR's diff.
resource "aws_instance" "my_instance" { | ||
ami = data.aws_ami.ubuntu.id | ||
instance_type = var.aws_instance_type | ||
key_name = aws_key_pair.terraweek_key.key_name | ||
security_groups = [aws_security_group.my_terraweek_sg.name] | ||
|
||
root_block_device { | ||
volume_size = var.aws_instance_volume_size | ||
volume_type = var.aws_instance_volume_type | ||
} | ||
|
||
tags = { | ||
Name = var.aws_instance_name | ||
} | ||
|
||
# Provisioner to install nginx on the instance after it's created | ||
provisioner "remote-exec" { | ||
inline = [ | ||
"sudo apt update", | ||
"sudo apt install -y nginx", | ||
"sudo systemctl start nginx", | ||
"sudo systemctl enable nginx" | ||
] | ||
|
||
# Use the private key for SSH authentication | ||
connection { | ||
type = "ssh" | ||
user = "ubuntu" | ||
private_key = file(var.aws_private_key_pair_name) | ||
host = self.public_ip | ||
} | ||
} | ||
|
||
# Lifecycle management configuration | ||
lifecycle { | ||
create_before_destroy = true # Create the new instance before destroying the old one | ||
prevent_destroy = false # Allow the resource to be destroyed | ||
ignore_changes = [tags] # Ignore changes to the tags | ||
} | ||
} |
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.
Enforce the use of Instance Metadata Service Version 2 (IMDSv2)
To enhance security, the EC2 instance should require IMDSv2, preventing certain types of attacks that exploit IMDSv1. You can enforce this by adding a metadata_options
block to the EC2 instance resource.
Apply this diff to enforce IMDSv2:
resource "aws_instance" "my_instance" {
ami = data.aws_ami.ubuntu.id
instance_type = var.aws_instance_type
key_name = aws_key_pair.terraweek_key.key_name
security_groups = [aws_security_group.my_terraweek_sg.name]
root_block_device {
volume_size = var.aws_instance_volume_size
volume_type = var.aws_instance_volume_type
}
+ metadata_options {
+ http_tokens = "required"
+ }
tags = {
Name = var.aws_instance_name
}
# Lifecycle management configuration
lifecycle {
create_before_destroy = true # Create the new instance before destroying the old one
prevent_destroy = false # Allow the resource to be destroyed
ignore_changes = [tags] # Ignore changes to the tags
}
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
resource "aws_instance" "my_instance" { | |
ami = data.aws_ami.ubuntu.id | |
instance_type = var.aws_instance_type | |
key_name = aws_key_pair.terraweek_key.key_name | |
security_groups = [aws_security_group.my_terraweek_sg.name] | |
root_block_device { | |
volume_size = var.aws_instance_volume_size | |
volume_type = var.aws_instance_volume_type | |
} | |
tags = { | |
Name = var.aws_instance_name | |
} | |
# Provisioner to install nginx on the instance after it's created | |
provisioner "remote-exec" { | |
inline = [ | |
"sudo apt update", | |
"sudo apt install -y nginx", | |
"sudo systemctl start nginx", | |
"sudo systemctl enable nginx" | |
] | |
# Use the private key for SSH authentication | |
connection { | |
type = "ssh" | |
user = "ubuntu" | |
private_key = file(var.aws_private_key_pair_name) | |
host = self.public_ip | |
} | |
} | |
# Lifecycle management configuration | |
lifecycle { | |
create_before_destroy = true # Create the new instance before destroying the old one | |
prevent_destroy = false # Allow the resource to be destroyed | |
ignore_changes = [tags] # Ignore changes to the tags | |
} | |
} | |
resource "aws_instance" "my_instance" { | |
ami = data.aws_ami.ubuntu.id | |
instance_type = var.aws_instance_type | |
key_name = aws_key_pair.terraweek_key.key_name | |
security_groups = [aws_security_group.my_terraweek_sg.name] | |
root_block_device { | |
volume_size = var.aws_instance_volume_size | |
volume_type = var.aws_instance_volume_type | |
} | |
metadata_options { | |
http_tokens = "required" | |
} | |
tags = { | |
Name = var.aws_instance_name | |
} | |
# Provisioner to install nginx on the instance after it's created | |
provisioner "remote-exec" { | |
inline = [ | |
"sudo apt update", | |
"sudo apt install -y nginx", | |
"sudo systemctl start nginx", | |
"sudo systemctl enable nginx" | |
] | |
# Use the private key for SSH authentication | |
connection { | |
type = "ssh" | |
user = "ubuntu" | |
private_key = file(var.aws_private_key_pair_name) | |
host = self.public_ip | |
} | |
} | |
# Lifecycle management configuration | |
lifecycle { | |
create_before_destroy = true # Create the new instance before destroying the old one | |
prevent_destroy = false # Allow the resource to be destroyed | |
ignore_changes = [tags] # Ignore changes to the tags | |
} | |
} |
🧰 Tools
🪛 checkov (3.2.312)
[HIGH] 67-106: Ensure Instance Metadata Service Version 1 is not enabled
(CKV_AWS_79)
variable "aws_private_key_pair_name" { | ||
description = "Path to the private key pair for SSH" | ||
type = string | ||
default = "~/terraweek-key" | ||
} |
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.
Use absolute paths or module-relative paths for key files
The default values for aws_private_key_pair_name
and aws_public_key_pair_name
use ~
and relative paths, which may not resolve correctly in Terraform. The tilde ~
is not expanded to the home directory, and relative paths could lead to file not found errors.
Apply this diff to specify absolute paths or use ${path.module}
for module-relative paths:
variable "aws_private_key_pair_name" {
description = "Path to the private key pair for SSH"
type = string
- default = "~/terraweek-key"
+ default = "/absolute/path/to/terraweek-key"
}
variable "aws_public_key_pair_name" {
description = "Path to the public key pair for SSH"
type = string
- default = "terraweek-key.pub"
+ default = "${path.module}/terraweek-key.pub"
}
Replace /absolute/path/to/terraweek-key
with the actual absolute path to your private key file. Using ${path.module}
ensures the path is relative to the module directory.
Also applies to: 30-34
variable "ssh_cidr" { | ||
description = "CIDR block for SSH access" | ||
type = string | ||
default = "0.0.0.0/0" | ||
} |
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.
Consider restricting CIDR blocks for inbound traffic
The default CIDR blocks for SSH, HTTP, and HTTPS access are set to "0.0.0.0/0"
, which allows traffic from anywhere. This can be a significant security risk. It's recommended to restrict access to trusted IP addresses or networks.
Update the default values to restrict access:
variable "ssh_cidr" {
description = "CIDR block for SSH access"
type = string
- default = "0.0.0.0/0"
+ default = "your-trusted-ip/32"
}
variable "http_cidr" {
description = "CIDR block for HTTP access"
type = string
- default = "0.0.0.0/0"
+ default = "your-trusted-network/24"
}
variable "https_cidr" {
description = "CIDR block for HTTPS access"
type = string
- default = "0.0.0.0/0"
+ default = "your-trusted-network/24"
}
Replace "your-trusted-ip/32"
and "your-trusted-network/24"
with your actual IP address or network range.
Also applies to: 72-76, 86-90
```hcl | ||
provisioner "remote-exec" { | ||
inline = [ | ||
"sudo apt update", | ||
"sudo apt install -y nginx", | ||
"sudo systemctl start nginx", | ||
"sudo systemctl enable nginx" | ||
] | ||
connection { | ||
type = "ssh" | ||
user = "ubuntu" | ||
private_key = file(var.aws_private_key_pair_name) | ||
host = self.public_ip | ||
} | ||
} | ||
``` |
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.
🛠️ Refactor suggestion
Enhance provisioner security and reliability
The provisioner block could be improved in several aspects:
- Add error handling for apt commands
- Pin the nginx version for consistency
- Verify the installation success
- Consider using a more secure approach for sudo commands
Consider this improved version:
provisioner "remote-exec" {
inline = [
- "sudo apt update",
- "sudo apt install -y nginx",
- "sudo systemctl start nginx",
- "sudo systemctl enable nginx"
+ "set -e", # Exit on any error
+ "sudo apt-get update && sudo apt-get install -y nginx=1.18.*",
+ "sudo systemctl start nginx || exit 1",
+ "sudo systemctl enable nginx || exit 1",
+ "sudo systemctl status nginx || exit 1" # Verify installation
]
connection {
type = "ssh"
user = "ubuntu"
private_key = file(var.aws_private_key_pair_name)
host = self.public_ip
+ timeout = "5m" # Add connection timeout
}
}
- **Configure AWS CLI Credentials:** | ||
|
||
Run the following command and enter your IAM user details: | ||
```bash | ||
aws configure | ||
``` | ||
|
||
Provide: | ||
- **Access Key ID** | ||
- **Secret Access Key** | ||
- **Default region** (e.g., `us-east-1`) | ||
- Output format (default: `json`) | ||
|
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.
🛠️ Refactor suggestion
Enhance AWS credentials security
The current AWS credentials configuration could be improved with more secure alternatives.
Consider adding these secure alternatives:
### Secure Alternatives for AWS Authentication
1. **AWS IAM Role** (Recommended for EC2):
```bash
# No credentials needed when using IAM roles
-
AWS SSO:
aws configure sso
-
Environment Variables:
export AWS_PROFILE=your-profile # Or export AWS_ACCESS_KEY_ID=your-access-key export AWS_SECRET_ACCESS_KEY=your-secret-key export AWS_SESSION_TOKEN=your-session-token # If using temporary credentials
⚠️ Security Note: Avoid storing credentials in plain text. Use AWS Secrets Manager or Parameter Store for production environments.
<!-- This is an auto-generated comment by CodeRabbit -->
resource "aws_s3_bucket" "example" { | ||
bucket = "example-bucket" | ||
tags = { | ||
Name = "example-bucket" | ||
} | ||
} | ||
``` |
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.
🛠️ Refactor suggestion
Add security best practices to resource examples
The example configurations should demonstrate security best practices.
Consider these improved examples:
resource "aws_s3_bucket" "example" {
bucket = "example-bucket"
+
+ # Enable versioning
+ versioning {
+ enabled = true
+ }
+
+ # Enable server-side encryption
+ server_side_encryption_configuration {
+ rule {
+ apply_server_side_encryption_by_default {
+ sse_algorithm = "AES256"
+ }
+ }
+ }
+
tags = {
Name = "example-bucket"
+ Environment = var.environment
}
}
data "aws_ami" "ubuntu" {
most_recent = true
+ owners = ["099720109477"] # Canonical's AWS account ID
+
filter {
name = "name"
values = ["ubuntu/images/*"]
}
+
+ filter {
+ name = "virtualization-type"
+ values = ["hvm"]
+ }
+
+ filter {
+ name = "root-device-type"
+ values = ["ebs"]
+ }
}
Also applies to: 207-214
```hcl | ||
terraform { | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = "5.65.0" | ||
} | ||
} | ||
} | ||
|
||
provider "aws" { | ||
region = "us-east-1" | ||
} | ||
``` |
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.
🛠️ Refactor suggestion
Improve AWS provider configuration flexibility
The current provider configuration could be enhanced for better maintainability and flexibility.
Consider this improved version:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
- version = "5.65.0"
+ version = "~> 5.65.0" # Allow minor version updates
}
}
}
provider "aws" {
- region = "us-east-1"
+ region = var.aws_region # Use variable for flexibility
+
+ default_tags {
+ tags = {
+ Environment = var.environment
+ ManagedBy = "Terraform"
+ }
+ }
}
Committable suggestion skipped: line range outside the PR's diff.
This pull request covers the tasks completed on Day-03 of TerraWeek. The configuration and setup focus on provisioning an AWS EC2 instance with Terraform, including state management and lifecycle handling. Key updates include:
AWS EC2 Instance Setup: Defined an EC2 instance along with necessary resources such as security groups, key pairs, and an Ubuntu AMI in
ec2.tf
. A provisioner is included to install and configure Nginx on the instance after creation.State File Management: Ensured state file checks before running
terraform plan
andterraform apply
. Configuredterraform validate
to verify the correctness of the setup.Provisioner Integration: Added a
remote-exec
provisioner in the EC2 instance configuration to automatically install and start Nginx once the instance is up.Lifecycle Configuration: Implemented lifecycle management for the EC2 instance in
ec2.tf
, which includes:create_before_destroy = true
: Ensures new resources are created before old ones are destroyed to avoid downtime.prevent_destroy = false
: Allows resources to be destroyed when needed.ignore_changes = [tags]
: Ensures that changes to tags are not tracked by Terraform.Terraform Commands: Demonstrated the usage of essential Terraform commands like
terraform validate
,terraform plan
,terraform apply
, andterraform destroy
for managing infrastructure state and lifecycle.Summary by CodeRabbit
Release Notes
New Features
Documentation
Enhancements