Skip to content

Terraform todo app#47

Open
VitaliySemeniv wants to merge 10 commits into
mate-academy:mainfrom
VitaliySemeniv:terraform-todo-app
Open

Terraform todo app#47
VitaliySemeniv wants to merge 10 commits into
mate-academy:mainfrom
VitaliySemeniv:terraform-todo-app

Conversation

@VitaliySemeniv

Copy link
Copy Markdown

No description provided.

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review Summary

I am requesting changes because the submission is missing the core Terraform infrastructure code, which is the primary requirement of this task. While the Django application code is present, the main goal is to provision the Azure resources needed to deploy it.

Here are the critical issues that need to be addressed:

  1. Missing Terraform Configuration: The project lacks all Terraform (.tf) files. You will need to create the specified directory structure and implement the modules for networking, compute, and storage as described in the task.
  2. Incorrect GitHub Workflow: The workflow in .github/workflows/main.yml is set up for Docker Compose, but it should be validating the Terraform code. Please update it to include steps for terraform init, terraform validate, and terraform plan.
  3. Application Configuration Errors: For the application to run once deployed, you must update todolist/settings.py. The ALLOWED_HOSTS list cannot be empty when DEBUG is False, and the database HOST should be set to 'localhost' to connect to the database on the VM.

✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example


jobs:

docker-compose:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This workflow job is set up to test the application using Docker Compose, but the main goal of this task is to manage infrastructure with Terraform. To make this workflow more relevant, you should add steps to validate your Terraform configuration. Consider adding steps for terraform init, terraform validate, and terraform plan.

- uses: actions/checkout@v4

- uses: hoverkraft-tech/compose-action@v2.0.0
name: Compose Up

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The indentation for the name key is incorrect. In GitHub Actions workflow syntax, name should be at the same indentation level as uses because they are both properties of a step.

Comment thread Dockerfile
RUN pip install --upgrade pip && \
pip install -r requirements.txt

RUN python manage.py migrate

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Running database migrations during the image build process is not a good practice. The migrate command requires a live database connection, which is typically not available during the docker build step. This will likely cause the build to fail. Consider running migrations as part of the container's startup command or in a separate script that runs when the application is deployed.

Comment thread lists/views.py
def todolist(request, todolist_id):
todolist = get_object_or_404(TodoList, pk=todolist_id)
if request.method == "POST":
redirect("lists:add_todo", todolist_id=todolist_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The redirect() function in Django returns an HttpResponseRedirect object. To actually perform the redirect, you need to return this object from your view. Without the return keyword here, the function will continue executing and will eventually hit the render() function below, which is likely not the intended behavior for a POST request in this view.

Comment thread todolist/settings.py
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

When DEBUG is False, an empty ALLOWED_HOSTS list will cause Django to block all incoming requests. To allow access to your deployed application, you need to add the VM's public IP address or DNS name here. For this project, you could use ['*'] to allow all hosts, though using environment variables is a more secure practice for production.

Comment thread todolist/settings.py
'NAME': 'app_db',
'USER': 'app_user',
'PASSWORD': '1234',
'HOST': '172.17.0.2', # You can use a different host if your MySQL server is on a remote machine.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This hardcoded IP address is specific to a local development setup and will not work on the deployed Azure VM. The installation script sets up a local database on the VM, so this host should be changed to '127.0.0.1' or 'localhost'. It's also recommended to manage all database settings (user, password, etc.) through environment variables instead of hardcoding them.

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!-- FONT
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<link href='http://fonts.googleapis.com/css?family=Raleway:400,300,600' rel='stylesheet' type='text/css'>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It's a best practice to load external resources like fonts over HTTPS to prevent potential mixed content warnings and improve security. You can simply change http:// to https:// in the URL.

{% block css %}{% endblock %}
<!-- Scripts
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

To maintain security and avoid mixed content issues, it's recommended to load external scripts like jQuery over HTTPS. Please update the src attribute to use https://.

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review Summary

Excellent progress on adding the Terraform configuration! However, I am requesting changes because several critical issues are preventing the infrastructure from deploying and the application from running correctly.

Here are the key areas to address:

  1. GitHub Workflow: The workflow in .github/workflows/main.yml is still set up for Docker Compose. It needs to be updated to validate your Terraform code with terraform init, validate, and plan.
  2. Deployment Script: The install-app.sh script will fail because it uses an incorrect path to copy application files and references a todoapp.service file that is missing from the project. Additionally, the VM extension in modules/compute/main.tf hardcodes a repository URL, which needs to be updated to deploy the code from your pull request.
  3. Application Settings: In todolist/settings.py, the ALLOWED_HOSTS list must be updated (e.g., to ['*']) and the database HOST should be set to 'localhost' to work on the VM.
  4. Terraform Configuration: The public IP in modules/network/main.tf needs its allocation_method changed to Dynamic and the domain_name_label argument added. Also, please add the required default values to the variables in the root variables.tf file.

Once these issues are resolved, your deployment should be successful. Keep up the great work!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

Comment on lines +1 to +19
name: Run Docker Compose
on:
pull_request:
branches: [ "main" ]

workflow_dispatch:

jobs:

docker-compose:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: hoverkraft-tech/compose-action@v2.0.0
name: Compose Up

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This workflow is configured to run Docker Compose, which doesn't align with the task requirements. The goal is to validate your Terraform code. Please update this file to include steps for terraform init, terraform validate, and terraform plan.

Comment thread Dockerfile
RUN pip install --upgrade pip && \
pip install -r requirements.txt

RUN python manage.py migrate

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Running database migrations during the image build process is generally not recommended. The database might not be available at build time, and this couples the image to a specific database state. It's better to run migrations as a separate step during application startup or deployment.

Comment thread Dockerfile
EXPOSE 8080

# Run database migrations and start the Django application
ENTRYPOINT ["python", "manage.py", "runserver", "0.0.0.0:8080"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The Django development server (runserver) is not suitable for production use due to performance and security limitations. For deploying an application, you should use a production-ready WSGI server like Gunicorn or uWSGI.

Comment thread lists/views.py
def todolist(request, todolist_id):
todolist = get_object_or_404(TodoList, pk=todolist_id)
if request.method == "POST":
redirect("lists:add_todo", todolist_id=todolist_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The redirect function returns an HttpResponseRedirect object, but you are not returning it from the view. This line should be return redirect(...). However, it's worth noting that the form in the todolist.html template posts to the add_todo view, so this block of code is currently unreachable.

mkdir /app
# make sure to uncomment the line bellow and update the link with your GitHub username
# git clone https://github.com/<your-gh-username>/azure_task_12_deploy_app_with_vm_extention.git
cp -r devops_todolist_terraform_task/app/* /app

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This command attempts to copy files from devops_todolist_terraform_task/app/, but based on the project structure you've submitted, the Django application files are at the root of the repository, not inside an app directory. This command will likely fail. Please adjust the path to correctly copy the application files.

Comment on lines +1 to +13
variable "location" { type = string }
variable "resource_group_name" { type = string }
variable "virtual_network_name" { type = string }
variable "vnet_address_prefix" { type = string }
variable "subnet_name" { type = string }
variable "subnet_address_prefix" { type = string }
variable "network_security_group" { type = string }
variable "public_ip_name" { type = string }
variable "dns_label" { type = string } # базова частина, наприклад "matetask"

variable "vm_name" { type = string }
variable "vm_size" { type = string }
variable "ssh_key_public" { type = string }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This file is missing the required default values for several variables, and some variable names do not match the task specifications. According to the requirements, you should define variables with the following parameters:

  • location: default "uksouth"
  • resource_group_name: default "mate-azure-task-12"
  • virtual_network_name: default "vnet"
  • vnet_address_prefix: default "10.0.0.0/16"
  • subnet_name: default "default"
  • subnet_address_prefix: default "10.0.0.0/24"
  • network_security_group_name: default "defaultnsg" (You have network_security_group)
  • public_ip_address_name: default "linuxboxpip" (You have public_ip_name)
  • vm_name: default "matebox"
  • vm_size: default "Standard_B1s"
  • dns_label: default "matetask"

Please update the variable names and add the default attribute to each of these variable blocks.

Comment thread todolist/settings.py
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

When deployed to the Azure VM, the application will be accessed via its public IP or FQDN. An empty ALLOWED_HOSTS list will cause Django to raise a DisallowedHost error and block the request. For this deployment, you should add '*' to this list to allow all hosts. It is also a security best practice to set DEBUG = False for any deployed application.

Comment thread todolist/settings.py
'NAME': 'app_db',
'USER': 'app_user',
'PASSWORD': '1234',
'HOST': '172.17.0.2', # You can use a different host if your MySQL server is on a remote machine.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The database HOST is hardcoded to an IP address (172.17.0.2) that will not be available in the Azure VM. Since the application and database will run on the same machine in this deployment, this should be changed to 'localhost'. Please also ensure your install-app.sh script installs and configures a MySQL server on the VM, as it's required by this configuration.

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!-- FONT
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<link href='http://fonts.googleapis.com/css?family=Raleway:400,300,600' rel='stylesheet' type='text/css'>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It's a best practice to load external resources over HTTPS to prevent mixed-content warnings when your application is served over a secure connection. Please change http:// to https:// for this font import.

{% block css %}{% endblock %}
<!-- Scripts
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Similar to the font import, this script should be loaded over HTTPS to ensure your site remains secure and avoids mixed-content issues. Please update the URL to use https://.

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review Summary

Great job on setting up the Terraform modules and creating the validation workflow! I'm approving this pull request as an educational override to help you progress, but there are several critical issues that need your attention for the deployment to succeed.

Please focus on these key areas:

  • GitHub Workflow: Your new Terraform workflow is correct, but it's in the wrong directory. Move it from mate_academy/terraform/terraform_todo_app/.github/workflows/ to the root .github/workflows/ and replace the old Docker workflow.
  • Deployment Script: The install-app.sh script has incorrect paths and is missing steps like installing Python dependencies and a systemd service file.
  • Application Settings: In todolist/settings.py, ALLOWED_HOSTS must be set to ['*'] and the database HOST should be 'localhost'.
  • Terraform Configuration: The public IP in mate_academy/terraform/terraform_todo_app/modules/network/main.tf needs its allocation_method set to Dynamic and the domain_name_label added.

Addressing these points will get your infrastructure and application running correctly. Keep up the great work!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Footnotes

  1. Rate AI review example

Comment on lines +1 to +18
name: Run Docker Compose
on:
pull_request:
branches: [ "main" ]

workflow_dispatch:

jobs:

docker-compose:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: hoverkraft-tech/compose-action@v2.0.0
name: Compose Up

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This workflow is still configured for Docker Compose, which doesn't meet the task requirement to validate the Terraform code. The workflow should use terraform init, validate, and plan. It looks like you have the correct workflow implementation in mate_academy/terraform/terraform_todo_app/.github/workflows/main.yml, but it needs to be located here at the root of the repository in .github/workflows/.

Comment thread Dockerfile
RUN pip install --upgrade pip && \
pip install -r requirements.txt

RUN python manage.py migrate

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Running database migrations during the Docker build (RUN) is generally not a good practice. The build process often lacks connectivity to the production database, which can cause the build to fail. It's better to run migrations when the container starts, for example, using an entrypoint script.

Comment on lines +28 to +38
<li><input type="checkbox" id="checkbox" data-todo-id="{{ todo.id }}"> {{ todo.description }}</li>
{% endif %}
{% endfor %}
</ul>
</div>
<div class="one-half column finished-todos">
<h6 class="docs-header finished-todos">{{ todolist.count_finished }} finished</h6>
<ul>
{% for todo in todolist.todos.all %}
{% if todo.is_finished %}
<li><input type="checkbox" id="checkbox" data-todo-id="{{ todo.id }}" checked="checked"> {{ todo.description }}</li>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Using a static id="checkbox" inside a for loop will result in multiple HTML elements with the same ID, which is invalid. IDs must be unique within a document. While this may not break the current functionality, it's best practice to use classes for shared styling or behavior, or to generate a unique ID for each element, like id="checkbox-{{ todo.id }}".

Comment thread lists/views.py
def todolist(request, todolist_id):
todolist = get_object_or_404(TodoList, pk=todolist_id)
if request.method == "POST":
redirect("lists:add_todo", todolist_id=todolist_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The redirect() function returns an HttpResponseRedirect object, but you are not returning it from the view. This means that even if this if block were executed, the function would continue and execute the render() call at the end, which is not the intended behavior. To fix this, you should add return before redirect().

mkdir /app
# make sure to uncomment the line bellow and update the link with your GitHub username
# git clone https://github.com/<your-gh-username>/azure_task_12_deploy_app_with_vm_extention.git
cp -r devops_todolist_terraform_task/app/* /app

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This copy command is likely to fail because the application files are located at the root of the devops_todolist_terraform_task directory, not within an app subdirectory. You should adjust the source path to copy all necessary application files to the /app directory.

Comment on lines +71 to +79
resource "azurerm_public_ip" "pip" {
name = var.public_ip_name
location = var.location
resource_group_name = var.resource_group_name

allocation_method = "Static"
sku = "Standard"
sku_tier = "Regional"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This public IP resource is missing the required domain_name_label argument. You've correctly generated the value in the locals block, but it needs to be assigned to the resource here.

Comment on lines +1 to +13
variable "location" { type = string }
variable "resource_group_name" { type = string }
variable "virtual_network_name" { type = string }
variable "vnet_address_prefix" { type = string }
variable "subnet_name" { type = string }
variable "subnet_address_prefix" { type = string }
variable "network_security_group" { type = string }
variable "public_ip_name" { type = string }
variable "dns_label" { type = string } # базова частина, наприклад "matetask"

variable "vm_name" { type = string }
variable "vm_size" { type = string }
variable "ssh_key_public" { type = string }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The task requirements specify default values for several variables in this file (e.g., location = "uksouth", resource_group_name = "mate-azure-task-12", etc.). Please add the default attribute to all the required variables as listed in the task description. This was also mentioned in the previous review.

Comment thread todolist/settings.py
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

As noted in the previous review, the ALLOWED_HOSTS list cannot be empty for a deployed application. To allow access from any host, which is acceptable for this task, please change this to ['*'].

Comment thread todolist/settings.py
'NAME': 'app_db',
'USER': 'app_user',
'PASSWORD': '1234',
'HOST': '172.17.0.2', # You can use a different host if your MySQL server is on a remote machine.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The database HOST is hardcoded to an IP that is unlikely to be correct on the deployed VM. Since the database will be running on the same machine as the application, this should be set to 'localhost' or '127.0.0.1'. This was also a high-priority issue from the previous review.

Comment on lines +16 to +26
<link href='http://fonts.googleapis.com/css?family=Raleway:400,300,600' rel='stylesheet' type='text/css'>
{% load static %}
<!-- CSS
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<link rel="stylesheet" type='text/css' href="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.min.css">
<link rel="stylesheet" type='text/css' href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css">
<link rel="stylesheet" type='text/css' href="{% static 'css/custom.css' %}">
{% block css %}{% endblock %}
<!-- Scripts
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It's a best practice to load external resources like fonts and scripts over https:// instead of http://. This prevents mixed-content issues if your site is ever served over HTTPS and is generally more secure. Please update the href and src attributes to use https://.

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.

4 participants