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

Integrate with Terraform #118

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -367,3 +367,34 @@ MigrationBackup/

# Fody - auto-generated XML schema
FodyWeavers.xsd

# Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log

# Exclude all .tfvars files, which are likely to contain sentitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
#
*.tfvars

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
*tfplan*

# Ignore CLI configuration files
.terraformrc
terraform.rc
Comment on lines +378 to +400
Copy link
Owner

Choose a reason for hiding this comment

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

I understand you referenced this from an online source, but I'm wondering if it seems like there's some inconsistency in the comments e.g. some start with Ignore, Exclude and Include.

45 changes: 45 additions & 0 deletions docs/IAC-Introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Introduction
## Background
Traditionally, to manage a piece of infrastructure hosted in a cloud provider, we would have to log into an administrative portal/console, and manually provision that infrastructure resource. This is fine if there are not a lot of resources to manage.

As the project gets more complex, there would be higher volatility in the infrastructure changes. For example, to scale up infrastructure for a peak day, sunsetting legacy infrastructures, etc. Managing infrastructure manually starts to get challenging as there are many changes to make.

## What is IaC?
Infrastructure as Code (IaC) is the idea of using code to create configuration files for managing a software infrastructure. By specifying infrastructure requirements and dependencies as code, we can then version, automate and release the changes on the infrastructure.

## What is Terraform?
Terraform is an open source Infrastructure as Code tool to automate the provisioning and management of Cloud infrastructures. The configuration files are written in the **HashiCorp Configuration Language(HCL)**. This language is written in `.tf` files.

## Terraform Architechture
```mermaid
flowchart TB
subgraph Plugins
Providers
Provisioners
end
id1[Terraform Core] -- RPC --> Plugins
Plugins -- golang --> id2[Client Libraries]
id2 -- "HTTP(s)" --> id3[Upstream APIs]
```
Terraform is mainly split into several parts:

**Terraform Core:** This is the binary that communicates with Terraform plugins to manage the infrastructure. It is responsible for reading configuration files, building the dependency graph and communicating with plugins over RPC.

**Terraform Plugins:** Plugins are executable binaries written in Go. Currently, there are 2 kinds of plugins: Providers and Provisioners. Providers expose implementations to services such as AWS, AzureRM. Provisioners run scripts during resource creation or destruction.

**Client Libraries:** Client libraries make it easier to communicate with services from a supported language. While it is possible to call the services' API directly, client libraries simplify the code you need to call them

## Terraform Workflow
The workflow for using Terraform consists of five stages: **Write, Initialisation, Plan, Apply/Destroy**

**Writing Terraform configuration files**

Writing the configuration files is the first step of using Terraform. The working directory should have at least include one `.tf` file written using HCL.

Several common practices when writing the config files are:
1. Store your config files in version control and make small incremental changes to them as you write them.
1. Repeatedly run commands `terraform init` or `terraform plan` to check and fix the syntax errors.

**Initialization**

When `terraform init` command is executed, Terraform Core reads the configuration files in the working directory, downloads the plugins from several sources, and generates a lock file for subsequent `terraform init` executions to decide which plugin versions to be used.
40 changes: 40 additions & 0 deletions terraform/terraform-create-resource/cosmosdb.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
resource "azurerm_cosmosdb_account" "storage" {
name = "cosmos-couplemgmt-${var.prefix}"
access_key_metadata_writes_enabled = true
analytical_storage_enabled = false
enable_automatic_failover = false
enable_multiple_write_locations = false
is_virtual_network_filter_enabled = false
kind = "GlobalDocumentDB"
local_authentication_disabled = false
Copy link
Owner

Choose a reason for hiding this comment

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

this is like double negative haha. I suppose there's no local_authentication_enabled?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is a fixed name for this argument. However, I found out it is optional and defaults to false. I will have it removed along with other optional arguments. Documentation can be found here: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_account

location = var.azurerm_region
network_acl_bypass_for_azure_services = false
network_acl_bypass_ids = []
offer_type = "Standard"
public_network_access_enabled = true
resource_group_name = azurerm_resource_group.app.name
# Only one free tier cosmosDB per subscription
# enable_free_tier = true

capabilities {
name = "EnableServerless"
}

backup {
interval_in_minutes = 240
retention_in_hours = 8
type = "Periodic"
}

consistency_policy {
consistency_level = "ConsistentPrefix"
max_interval_in_seconds = 5
max_staleness_prefix = 100
}

geo_location {
failover_priority = 0
location = "southeastasia"
zone_redundant = false
}
}
61 changes: 61 additions & 0 deletions terraform/terraform-create-resource/functionapp.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
resource "azurerm_app_service_plan" "changeevent" {
name = "changeevent-service-plan"
location = var.azurerm_region
resource_group_name = azurerm_resource_group.app.name
kind = "FunctionApp"

sku {
tier = "Dynamic"
size = "Y1"
}
}

resource "azurerm_function_app" "changeevent" {
name = "func-changeevent.azurewebsites.net"
location = var.azurerm_region
resource_group_name = azurerm_resource_group.app.name
app_service_plan_id = azurerm_app_service_plan.change_event_asp.id
storage_account_name = azurerm_storage_account.storage.name
storage_account_access_key = azurerm_storage_account.storage.primary_access_key

app_settings = {
"AccountEndpoint" = azurerm_cosmosdb_account.storage.endpoint
"AccountKey" = azurerm_cosmosdb_account.storage.primary_key
"DatabaseConnectionString" = azurerm_cosmosdb_account.storage.connection_strings[0]
"DatabaseName" = "database"
"ImagesConnectionString" = "DefaultEndpointsProtocol=https;AccountName=${azurerm_storage_account.storage.name};AccountKey=${azurerm_storage_account.storage.primary_access_key};EndpointSuffix=core.windows.net"
"FUNCTIONS_WORKER_RUNTIME" = "dotnet"
"WEBSITE_RUN_FROM_PACKAGE" = "1"
}
}

resource "azurerm_app_service_plan" "couple_api" {
name = "coupleapi-service-plan"
location = var.azurerm_region
resource_group_name = azurerm_resource_group.app.name
kind = "FunctionApp"

sku {
tier = "Dynamic"
size = "Y1"
}
}

resource "azurerm_function_app" "coupleapi" {
name = "func-coupleapi.azurewebsites.net"
location = var.azurerm_region
resource_group_name = azurerm_resource_group.app.name
app_service_plan_id = azurerm_app_service_plan.couple_api_asp.id
storage_account_name = azurerm_storage_account.storage.name
storage_account_access_key = azurerm_storage_account.storage.primary_access_key

app_settings = {
"AccountEndpoint" = azurerm_cosmosdb_account.storage.endpoint
"AccountKey" = azurerm_cosmosdb_account.storage.primary_key
"DatabaseConnectionString" = azurerm_cosmosdb_account.storage.connection_strings[0]
"DatabaseName" = "database"
"ImagesConnectionString" = "DefaultEndpointsProtocol=https;AccountName=${azurerm_storage_account.storage.name};AccountKey=${azurerm_storage_account.storage.primary_access_key};EndpointSuffix=core.windows.net"
"FUNCTIONS_WORKER_RUNTIME" = "dotnet"
"WEBSITE_RUN_FROM_PACKAGE" = "1"
}
}
25 changes: 25 additions & 0 deletions terraform/terraform-create-resource/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
terraform {
required_version = ">=0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.91.0"
}
}

backend "azurerm" {
resource_group_name = "rg-couplemgmt-tfstate"
storage_account_name = "stcouplemgmtstate"
container_name = "container-tfstate"
key = "terraform.tfstate"
}
}

provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "app" {
name = "rg-couplemgmt"
location = var.azurerm_region
}
14 changes: 14 additions & 0 deletions terraform/terraform-create-resource/storage.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
resource "azurerm_storage_account" "images" {
name = "stcouplemgmtimages"
resource_group_name = azurerm_resource_group.app.name
location = var.azurerm_region
account_tier = "Standard"
account_replication_type = "LRS"
allow_blob_public_access = true
}

resource "azurerm_storage_container" "images" {
name = "container-images"
storage_account_name = azurerm_storage_account.images.name
container_access_type = "private"
}
13 changes: 13 additions & 0 deletions terraform/terraform-create-resource/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Shortnames for regions can be found here:
# https://github.com/claranet/terraform-azurerm-regions/blob/master/REGIONS.md
variable "azurerm_region" {
description = "Standard Azure region in shortname format for resource naming purpose"
type = string
default = "southeastasia"
}

variable "env" {
description = "Environment for resource names"
type = string
default = "test"
}
18 changes: 18 additions & 0 deletions terraform/terraform-remote-state/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
terraform {
required_version = ">=0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.91.0"
}
}
}

provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "tfstate" {
name = "rg-couplemgmt-tfstate"
location = var.azurerm_region
}
16 changes: 16 additions & 0 deletions terraform/terraform-remote-state/storage.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
resource "azurerm_storage_account" "tfstate" {
name = "stcouplemgmtstate"
resource_group_name = azurerm_resource_group.tfstate.name
location = var.azurerm_region
account_tier = "Standard"
account_replication_type = "LRS"
account_kind = "StorageV2"
access_tier = "Hot"
allow_blob_public_access = true
}

resource "azurerm_storage_container" "tfstate" {
name = "container-tfstate"
storage_account_name = azurerm_storage_account.tfstate.name
container_access_type = "blob"
}
7 changes: 7 additions & 0 deletions terraform/terraform-remote-state/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Shortnames for regions can be found here:
# https://github.com/claranet/terraform-azurerm-regions/blob/master/REGIONS.md
Comment on lines +1 to +2
Copy link
Owner

Choose a reason for hiding this comment

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

I notice this being repeated in the other variables.tf file as well. I wonder if this should be documented in a centralised location instead.

variable "azurerm_region" {
description = "Standard Azure region in shortname format for resource naming purpose"
type = string
default = "southeastasia"
}