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

Added solution.md with images for Day-03: Terraform Configuration for AWS EC2 Instance with Provisioners, State Management, and Lifecycle Configuration #23

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

Amitabh-DevOps
Copy link

@Amitabh-DevOps Amitabh-DevOps commented Dec 6, 2024

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 and terraform apply. Configured terraform 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, and terraform destroy for managing infrastructure state and lifecycle.

Summary by CodeRabbit

Release Notes

  • New Features

    • Comprehensive guide on Terraform basics and installation for AWS.
    • Introduction of Terraform configuration files for managing AWS resources, including EC2 instances, security groups, and key pairs.
    • New variables for customizable AWS infrastructure deployment.
  • Documentation

    • Detailed instructions on using HashiCorp Configuration Language (HCL) in Terraform.
    • Structured guides for setting up Terraform and managing AWS resources.
  • Enhancements

    • Outputs for public and private IP addresses of EC2 instances added for easier access.

Copy link

coderabbitai bot commented Dec 6, 2024

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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.

📥 Commits

Reviewing files that changed from the base of the PR and between 6a69991 and 46e1606.

Walkthrough

The changes introduce several new Terraform configuration files and guides for managing AWS resources. The solution.md files provide comprehensive instructions on Terraform basics, installation, and using HashiCorp Configuration Language (HCL). The main.tf, variable.tf, ec2.tf, output.tf, and terraform.tf files define the necessary configurations for deploying AWS resources, including EC2 instances, security groups, and key pairs. New variables and outputs are added to facilitate customization and retrieval of instance information.

Changes

File Change Summary
day01/solution.md Introduced a guide on Terraform basics and installation for AWS, including key terminologies.
day02/main.tf Added configuration for AWS provider with region set to us-west-2.
day02/solution.md Provided a structured guide for using HCL, including tasks for syntax, variables, and configurations.
day02/variable.tf Introduced a new variable bucket_name for S3 bucket naming.
day03/ec2.tf Added configurations for managing AWS infrastructure: AMI data source, EC2 instance, security group, etc.
day03/main.tf Configured AWS provider with a variable for the region.
day03/output.tf Introduced outputs for EC2 public and private IP addresses.
day03/solution.md Documented the setup and management of an AWS EC2 instance, including lifecycle management.
day03/terraform.tf Added a configuration block for required providers, specifying AWS provider version constraints.
day03/variable.tf Introduced multiple variables for configuring AWS resources, including AMI owners and instance types.

Poem

🐇 In the garden of code, we hop with glee,
Terraform's magic, as bright as can be.
With variables dancing, and instances in flight,
We build our dreams, from morning till night.
So let’s raise our paws, to the cloud up above,
For infrastructure crafted with care and with love! 🌼


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?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Amitabh-DevOps
Copy link
Author

@coderabbitai full review

Copy link

coderabbitai bot commented Dec 6, 2024

✅ Actions performed

Full review triggered.

Copy link

@coderabbitai coderabbitai bot left a 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 using aws_default_vpc; consider creating a custom VPC instead

Using 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 heading

The 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 implications

While 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 practices

The 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 considerations

The documentation would benefit from:

  1. Consistent heading hierarchy
  2. A dedicated security considerations section
  3. 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: ...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)

🪛 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

📥 Commits

Reviewing files that changed from the base of the PR and between 6a69991 and 46e1606.

⛔ 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.

Comment on lines +29 to +35
ingress {
description = "Allow access to SSH port 22"
from_port = 22
to_port = 22
protocol = var.ssh_protocol
cidr_blocks = [var.ssh_cidr]
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Comment on lines +83 to +98
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
}
}
Copy link

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.

Comment on lines +67 to +106
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
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
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)

Comment on lines +23 to +27
variable "aws_private_key_pair_name" {
description = "Path to the private key pair for SSH"
type = string
default = "~/terraweek-key"
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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

Comment on lines +58 to +62
variable "ssh_cidr" {
description = "CIDR block for SSH access"
type = string
default = "0.0.0.0/0"
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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

Comment on lines +74 to +89
```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
}
}
```
Copy link

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:

  1. Add error handling for apt commands
  2. Pin the nginx version for consistency
  3. Verify the installation success
  4. 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
   }
 }

Comment on lines +107 to +119
- **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`)

Copy link

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
  1. AWS SSO:

    aws configure sso
  2. 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 -->

Comment on lines +171 to +177
resource "aws_s3_bucket" "example" {
bucket = "example-bucket"
tags = {
Name = "example-bucket"
}
}
```
Copy link

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

Comment on lines +131 to +144
```hcl
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.65.0"
}
}
}

provider "aws" {
region = "us-east-1"
}
```
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant