Skip to content

Commit bccf088

Browse files
Exercise 12
1 parent 723e704 commit bccf088

File tree

8 files changed

+233
-14
lines changed

8 files changed

+233
-14
lines changed

.dockerignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,41 @@ ansible
1111
.gitpod.yml
1212
.python-version
1313
Dockerfile
14+
15+
# Local .terraform directories
16+
**/.terraform/*
17+
18+
# .tfstate files
19+
*.tfstate
20+
*.tfstate.*
21+
22+
# Crash log files
23+
crash.log
24+
crash.*.log
25+
26+
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
27+
# password, private keys, and other secrets. These should not be part of version
28+
# control as they are data points which are potentially sensitive and subject
29+
# to change depending on the environment.
30+
*.tfvars
31+
*.tfvars.json
32+
33+
# Ignore override files as they are usually used to override resources locally and so
34+
# are not checked in
35+
override.tf
36+
override.tf.json
37+
*_override.tf
38+
*_override.tf.json
39+
40+
# Ignore transient lock info files created by terraform apply
41+
.terraform.tfstate.lock.info
42+
43+
# Include override files you do wish to add to version control using negated pattern
44+
# !example_override.tf
45+
46+
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
47+
# example: *tfplan*
48+
49+
# Ignore CLI configuration files
50+
.terraformrc
51+
terraform.rc

.github/workflows/my-pipeline.yml

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ jobs:
2121
- run: docker run --entrypoint poetry todo-app:test run safety check
2222
continue-on-error: true
2323

24-
deploy:
25-
name: Build docker image and deploy to production
24+
build-and-push:
25+
name: Build docker image and push to docker hub
2626
runs-on: ubuntu-latest
2727
needs: test
2828
if: github.ref_name == github.event.repository.default_branch
@@ -41,7 +41,23 @@ jobs:
4141
with:
4242
push: true
4343
tags: aleyipsoftwire/todo-app:prod
44-
- name: Release to Azure
44+
45+
apply-terraform-and-deploy:
46+
name: Apply terraform changes and deploy to Azure
47+
runs-on: ubuntu-latest
48+
needs: build-and-push
49+
env:
50+
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
51+
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
52+
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
53+
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
54+
steps:
55+
- uses: actions/checkout@v4
56+
- name: Initialise terraform
57+
run: terraform init
58+
- name: Apply terraform changes
4559
env:
46-
AZURE_WEBHOOK: ${{ secrets.AZURE_WEBHOOK }}
47-
run: curl -X POST "$AZURE_WEBHOOK"
60+
TF_VAR_prefix: "live"
61+
run: terraform apply -auto-approve
62+
- name: Release to Azure
63+
run: curl -X POST "$(terraform output -raw webhook_url)"

.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,41 @@ env/
118118

119119
### Configuration files ###
120120
.env
121+
122+
# Local .terraform directories
123+
**/.terraform/*
124+
125+
# .tfstate files
126+
*.tfstate
127+
*.tfstate.*
128+
129+
# Crash log files
130+
crash.log
131+
crash.*.log
132+
133+
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
134+
# password, private keys, and other secrets. These should not be part of version
135+
# control as they are data points which are potentially sensitive and subject
136+
# to change depending on the environment.
137+
*.tfvars
138+
*.tfvars.json
139+
140+
# Ignore override files as they are usually used to override resources locally and so
141+
# are not checked in
142+
override.tf
143+
override.tf.json
144+
*_override.tf
145+
*_override.tf.json
146+
147+
# Ignore transient lock info files created by terraform apply
148+
.terraform.tfstate.lock.info
149+
150+
# Include override files you do wish to add to version control using negated pattern
151+
# !example_override.tf
152+
153+
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
154+
# example: *tfplan*
155+
156+
# Ignore CLI configuration files
157+
.terraformrc
158+
terraform.rc

.terraform.lock.hcl

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,19 @@ docker run -dit \
152152
2. Building the image, with `docker build --target production --tag <user_name>/todo-app:prod .`
153153
3. Pushing the image, with `docker push <user_name>/todo_app:prod`
154154

155-
### Deploying to Azure App Services
156-
157-
1. First create an App Service Plan:
158-
`az appservice plan create --resource-group <resource_group_name> -n <appservice_plan_name> --sku B1 --is-linux`
159-
2. Then create the Web App:
160-
`az webapp create --resource-group <resource_group_name> --plan <appservice_plan_name> --name <webapp_name> --deployment-container-image-name docker.io/<user_name>/todo-app:prod`
161-
3. Set up environment variables individually via
162-
`az webapp config appsettings set -g <resource_group_name> -n <webapp_name> --settings FLASK_APP=todo_app/app`
163-
4. The app should now be deployed to `http://<webapp_name>.azurewebsites.net/`
155+
### Terraform
156+
157+
1. Follow
158+
[this tutorial](https://docs.microsoft.com/en-us/azure/developer/terraform/store-state-in-azure-storage#configure-storage-account)
159+
to set up a storage account
160+
2. Update the following values in `main.tf`:
161+
* `resource_group_name` (there are multiple instances)
162+
* `storage_account_name`
163+
* `container_name`
164+
* `subscription_id`
165+
* `docker_image_name`
166+
3. Run `terraform init`
167+
4. Run `terraform apply`
164168

165169
### Update the image
166170

main.tf

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
terraform {
2+
required_providers {
3+
azurerm = {
4+
source = "hashicorp/azurerm"
5+
version = ">= 3.8"
6+
}
7+
}
8+
9+
backend "azurerm" {
10+
resource_group_name = "cohort32-33_AleYip_ProjectExercise"
11+
storage_account_name = "m12tfstore"
12+
container_name = "m12-tf-store-container"
13+
key = "terraform.tfstate"
14+
}
15+
}
16+
17+
provider "azurerm" {
18+
features {}
19+
subscription_id = "d33b95c7-af3c-4247-9661-aa96d47fccc0"
20+
}
21+
22+
data "azurerm_resource_group" "main" {
23+
name = "cohort32-33_AleYip_ProjectExercise"
24+
}
25+
26+
resource "azurerm_service_plan" "main" {
27+
name = "${var.prefix}-terraformed-asp"
28+
location = data.azurerm_resource_group.main.location
29+
resource_group_name = data.azurerm_resource_group.main.name
30+
os_type = "Linux"
31+
sku_name = "B1"
32+
}
33+
34+
resource "azurerm_linux_web_app" "main" {
35+
name = "${var.prefix}-aleyipsoftwire-m12-exercise"
36+
location = data.azurerm_resource_group.main.location
37+
resource_group_name = data.azurerm_resource_group.main.name
38+
service_plan_id = azurerm_service_plan.main.id
39+
40+
site_config {
41+
application_stack {
42+
docker_image_name = "aleyipsoftwire/todo-app:prod"
43+
docker_registry_url = "https://docker.io"
44+
}
45+
}
46+
47+
app_settings = {
48+
WEBSITES_PORT = 8000
49+
MONGODB_PRIMARY_CONNECTION_STRING = azurerm_cosmosdb_account.main.primary_mongodb_connection_string
50+
}
51+
}
52+
53+
resource "azurerm_cosmosdb_account" "main" {
54+
name = "${var.prefix}-aleyipsoftwire-m12-mongodb-cluster"
55+
location = data.azurerm_resource_group.main.location
56+
resource_group_name = data.azurerm_resource_group.main.name
57+
offer_type = "Standard"
58+
kind = "MongoDB"
59+
60+
automatic_failover_enabled = true
61+
62+
capabilities {
63+
name = "EnableMongo"
64+
}
65+
66+
capabilities {
67+
name = "EnableServerless"
68+
}
69+
70+
consistency_policy {
71+
consistency_level = "BoundedStaleness"
72+
max_interval_in_seconds = 300
73+
max_staleness_prefix = 100000
74+
}
75+
76+
geo_location {
77+
location = "uksouth"
78+
failover_priority = 0
79+
}
80+
81+
lifecycle {
82+
prevent_destroy = true
83+
}
84+
}
85+
86+
resource "azurerm_cosmosdb_mongo_database" "main" {
87+
name = "todo-app-db"
88+
resource_group_name = data.azurerm_resource_group.main.name
89+
account_name = azurerm_cosmosdb_account.main.name
90+
}

outputs.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
output "webapp_url" {
2+
value = "https://${azurerm_linux_web_app.main.default_hostname}"
3+
}
4+
5+
output "webhook_url" {
6+
value = "https://${azurerm_linux_web_app.main.site_credential[0].name}:${azurerm_linux_web_app.main.site_credential[0].password}@${azurerm_linux_web_app.main.name}.scm.azurewebsites.net/docker/hook"
7+
sensitive = true
8+
}

variables.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
variable "prefix" {
2+
description = "The prefix used for all resources in this environment"
3+
}

0 commit comments

Comments
 (0)