Skip to content

Commit

Permalink
ECI-394 Add docker login and function app modules (#21)
Browse files Browse the repository at this point in the history
* Add Function App Module

* Add container registry login functionality

* reviewers comments

* add service user optionality

* ECI-394 Add function module and complete container registry module. (#22)

* build and push image

* Add function module

* uncomment accidental comments

* remove unnecessary code

* Update datadog-logs-oci-orm/modules/containerregistry/locals.tf
  • Loading branch information
sva91 authored Dec 26, 2024
1 parent 4442a73 commit 758816e
Show file tree
Hide file tree
Showing 22 changed files with 554 additions and 33 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
**/.terraform/**
**/.terraform.lock.hcl
**/.DS_Store
**/terraform.tfstate
**/terraform.tfstate.backup
**/terraform.tfvars
11 changes: 0 additions & 11 deletions datadog-logs-oci-orm/data.tf

This file was deleted.

10 changes: 0 additions & 10 deletions datadog-logs-oci-orm/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,3 @@ locals {
datadog-terraform = "true"
}
}

locals {
# Name for tenancy namespace, metadata and regions
oci_regions = tomap({
for reg in data.oci_identity_region_subscriptions.subscriptions.region_subscriptions :
reg.region_name => reg
})
oci_region_key = lower(local.oci_regions[var.region].region_key)
tenancy_home_region = data.oci_identity_tenancy.tenancy_metadata.home_region_key
}
34 changes: 34 additions & 0 deletions datadog-logs-oci-orm/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,37 @@ module "policy" {
resource_name_prefix = var.resource_name_prefix
freeform_tags = local.freeform_tags
}

module "functionapp" {
source = "./modules/functionapp"
compartment_ocid = var.compartment_ocid
freeform_tags = local.freeform_tags
resource_name_prefix = var.resource_name_prefix
function_app_shape = var.function_app_shape
subnet_ocid = module.vcn.vcn_network_details.subnet_id
datadog_api_key = var.datadog_api_key
datadog_endpoint = var.datadog_endpoint
datadog_tags = var.datadog_tags
}

module "containerregistry" {
source = "./modules/containerregistry"
region = var.region
tenancy_ocid = var.tenancy_ocid
user_ocid = var.service_user_ocid == "" ? var.current_user_ocid : var.service_user_ocid
auth_token_description = var.auth_token_description
auth_token = var.auth_token
resource_name_prefix = var.resource_name_prefix
compartment_ocid = var.compartment_ocid
freeform_tags = local.freeform_tags
count = var.function_image_path == "" ? 1 : 0
}

module "function" {
depends_on = [module.containerregistry]
source = "./modules/function"
freeform_tags = local.freeform_tags
function_app_name = module.functionapp.function_app_details.function_app_name
function_app_ocid = module.functionapp.function_app_details.function_app_ocid
function_image_path = var.function_image_path == "" ? module.containerregistry[0].containerregistry_details.function_image_path : var.function_image_path
}
8 changes: 8 additions & 0 deletions datadog-logs-oci-orm/modules/containerregistry/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
data "oci_objectstorage_namespace" "namespace" {
compartment_id = var.tenancy_ocid
}

data "oci_identity_user" "docker_user" {
#Required
user_id = var.user_ocid
}
9 changes: 9 additions & 0 deletions datadog-logs-oci-orm/modules/containerregistry/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
locals {
# OCI docker repository
registry_domain = "ocir.${var.region}.oci.oraclecloud.com"
tenancy_namespace = data.oci_objectstorage_namespace.namespace.namespace
function_name = "datadog-function-logs"
repo_name = "${var.resource_name_prefix}-functions/${local.function_name}"
docker_image_path = "${local.registry_domain}/${local.tenancy_namespace}/${local.repo_name}"
username = data.oci_identity_user.docker_user.name
}
81 changes: 81 additions & 0 deletions datadog-logs-oci-orm/modules/containerregistry/login.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
resource "null_resource" "recreate_auth_token" {
count = "${var.auth_token != "" ? 0 : 1}"
provisioner "local-exec" {
command = <<EOT
#!/bin/bash
set -e
# Step 1: List existing auth tokens
echo "Listing existing auth tokens..."
existing_token_ocid=$(oci iam auth-token list --user-id ${var.user_ocid} \
--query "data[?description=='${var.auth_token_description}'].id | [0]" --raw-output)
if [ "$existing_token_ocid" != "" ]; then
echo "Deleting existing auth token: $existing_token_ocid"
oci iam auth-token delete --user-id ${var.user_ocid} --auth-token-id $existing_token_ocid --force
else
# Check the total number of existing tokens
total_tokens=$(oci iam auth-token list --user-id ${var.user_ocid} --query "length(data)" --raw-output)
if [ "$total_tokens" -eq 2 ]; then
echo "Error: Total existing tokens are equal to 2. Cannot create a new token."
exit 1
fi
echo "No existing auth token with description '${var.auth_token_description}' found. Proceeding to create a new one."
fi
# Step 2: Create a new auth token
echo "Creating a new auth token..."
new_token_value=$(oci iam auth-token create --user-id ${var.user_ocid} \
--description "${var.auth_token_description}" --query "data.token" --raw-output)
# Step 3: Sleep for 30 seconds to ensure token propagation
echo "Waiting for 60 seconds to ensure token availability..."
sleep 60
echo $new_token_value > /tmp/new_auth_token.txt
EOT
}
triggers = {
always_run = "${timestamp()}"
}
}

resource "null_resource" "Login2OCIR" {
depends_on = [null_resource.recreate_auth_token]
provisioner "local-exec" {
command = <<EOT
#!/bin/bash
set -e
# Run the current command
if [ "${var.auth_token}" != "" ]; then
auth_token="${var.auth_token}"
else
auth_token=$(cat /tmp/new_auth_token.txt && rm -f /tmp/new_auth_token.txt)
fi
for i in {1..5}; do
echo "$auth_token" | docker login ${local.registry_domain} --username ${local.tenancy_namespace}/${local.username} --password-stdin && break
echo "Retrying Docker login... attempt $i"
sleep 10
done
# Check if login was successful
if [ $i -eq 5 ]; then
echo "Error: Docker login failed after 5 attempts. Trying to login through Oracle Identity Cloud Service"
for j in {1..5}; do
echo "$auth_token" | docker login ${local.registry_domain} --username ${local.tenancy_namespace}/oracleidentitycloudservice/$username --password-stdin && break
echo "Retrying Docker login through Identity service... attempt $j"
sleep 5
done
if [ $j -eq 5 ]; then
echo "Error: Docker login failed after 5 attempts."
exit 1
fi
fi
EOT
}
triggers = {
always_run = "${timestamp()}"
}
}
47 changes: 47 additions & 0 deletions datadog-logs-oci-orm/modules/containerregistry/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
### Repository in the Container Image Registry for the container images underpinning the function
resource "oci_artifacts_container_repository" "function_repo" {
# note: repository = store for all images versions of a specific container image - so it included the function name
depends_on = [null_resource.Login2OCIR]
compartment_id = var.compartment_ocid
display_name = "${local.repo_name}"
is_public = false
defined_tags = {}
freeform_tags = var.freeform_tags
}

# ### build the function into a container image and push that image to the repository in the OCI Container Image Registry
resource "null_resource" "FnImagePushToOCIR" {
depends_on = [oci_artifacts_container_repository.function_repo, null_resource.Login2OCIR]
#Delete the local image, if it exists
provisioner "local-exec" {
command = "image=$(docker images | grep ${local.docker_image_path} | awk -F ' ' '{print $3}') ; docker rmi -f $image &> /dev/null ; echo $image"
working_dir = "logs-function"
}

provisioner "local-exec" {
command = <<EOT
#!/bin/bash
set -e
TIMESTAMP=$(date +%s)
docker build -t ${local.docker_image_path}:latest --no-cache -t ${local.docker_image_path}:$TIMESTAMP . || { echo \"Build failed!\"; exit 1; }
docker push ${local.docker_image_path}:latest || { echo \"Docker push latest tagged image failed!\"; exit 1; }
docker push ${local.docker_image_path}:$TIMESTAMP || { echo \"Docker push timestamp tagged image failed!\"; exit 1; }
EOT
working_dir = "logs-function"
}

# remove function image (if it exists) from local container registry
provisioner "local-exec" {
command = "docker rmi -f `docker images | grep ${local.docker_image_path} | awk -F ' ' '{print $3}'` &> /dev/null"
working_dir = "logs-function"
}
}

resource "null_resource" "wait_for_image" {
depends_on = [null_resource.FnImagePushToOCIR]
provisioner "local-exec" {
command = "sleep 60"
}
}
8 changes: 8 additions & 0 deletions datadog-logs-oci-orm/modules/containerregistry/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
output "containerregistry_details" {
description = "Output of pushing image to container registry"
value = {
repository_ocid = oci_artifacts_container_repository.function_repo.id
repository_name = oci_artifacts_container_repository.function_repo.display_name
function_image_path = "${local.docker_image_path}:latest"
}
}
41 changes: 41 additions & 0 deletions datadog-logs-oci-orm/modules/containerregistry/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
variable "tenancy_ocid" {
type = string
description = "OCI tenant OCID, more details can be found at https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#five"
}

variable "user_ocid" {
type = string
description = "OCID of the user for managing docker images"
}

variable "compartment_ocid" {
type = string
description = "The OCID of the compartment where the container repository will be created"
}

variable "freeform_tags" {
type = map(string)
description = "A map of freeform tags to apply to the resources"
default = {}
}

variable "resource_name_prefix" {
type = string
description = "The prefix for the name of all of the resources"
}

variable "region" {
type = string
description = "OCI Region as documented at https://docs.cloud.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm"
}

variable "auth_token_description" {
description = "The description of the auth token to use for container registry login"
type = string
}

variable "auth_token" {
type = string
description = "The user auth token for docker login to OCI container registry."
sensitive = true
}
3 changes: 3 additions & 0 deletions datadog-logs-oci-orm/modules/function/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
locals {
function_name = "${var.function_app_name}-logs-function"
}
11 changes: 11 additions & 0 deletions datadog-logs-oci-orm/modules/function/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "oci_functions_function" "logs_function" {
#Required
application_id = var.function_app_ocid
display_name = local.function_name
memory_in_mbs = "256"

#Optional
defined_tags = {}
freeform_tags = var.freeform_tags
image = var.function_image_path
}
7 changes: 7 additions & 0 deletions datadog-logs-oci-orm/modules/function/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "function_details" {
description = "Output of function creation"
value = {
function_ocid = oci_functions_function.logs_function.id
function_name = oci_functions_function.logs_function.display_name
}
}
20 changes: 20 additions & 0 deletions datadog-logs-oci-orm/modules/function/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
variable "freeform_tags" {
type = map(string)
description = "A map of freeform tags to apply to the resources"
default = {}
}

variable "function_image_path" {
type = string
description = "The full path of the function image. The image should be present in the container registry for the region"
}

variable "function_app_name" {
type = string
description = "The name of the function application"
}

variable "function_app_ocid" {
type = string
description = "The OCID of the function application"
}
3 changes: 3 additions & 0 deletions datadog-logs-oci-orm/modules/functionapp/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
locals {
function_app_name = "${var.resource_name_prefix}-function-app"
}
18 changes: 18 additions & 0 deletions datadog-logs-oci-orm/modules/functionapp/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
resource "oci_functions_application" "logs_function_app" {
compartment_id = var.compartment_ocid
config = {
"DATADOG_HOST" = var.datadog_endpoint
"DATADOG_TOKEN" = var.datadog_api_key
"DD_COMPRESS" = "true"
"DATADOG_TAGS" = var.datadog_tags
}
defined_tags = {}
display_name = "${local.function_app_name}"
freeform_tags = var.freeform_tags
network_security_group_ids = [
]
shape = var.function_app_shape
subnet_ids = [
var.subnet_ocid,
]
}
7 changes: 7 additions & 0 deletions datadog-logs-oci-orm/modules/functionapp/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "function_app_details" {
description = "Output of creating function application"
value = {
function_app_ocid = oci_functions_application.logs_function_app.id
function_app_name = oci_functions_application.logs_function_app.display_name
}
}
Loading

0 comments on commit 758816e

Please sign in to comment.