Meme Analyzer = Memealyzer
The repo demonstrates Azure SDK usage via a complete application. This application takes in an image, uploads it to Blog Storage and enqueues a message into a Queue. A process receives that message and uses Form Recognizer to extract the text from the image, then uses Text Analytics to get the sentiment of the text, and then stores the results in Cosmos DB or Azure Table Storage.
If the text in the image is positive then the border color will change to green, if neutral then black, and if negative it will change to red.
Download the Azure SDK
This is the current .NET architecture - we are in the process of developing for other languages and architectures as well.
The following are required to run this application.
- A Terminal - WSL, GitBash, PowerShell. The Terraform deployment will not work with Windows Command Prompt because it uses some shell scripts to fill Terraform gaps. You will need to run all the commands below in your selected terminal.
- Install Azure CLI
- Install Terraform
- Install Git
- Install VS Code
- Install Docker
- Azure Subscription
The following Azure resources will be deployed with the Terraform script.
- Resource Group
- Storage Account
- Cognitive Services Form Recognizer
- Cognitive Services Text Analytics
- Cosmos DB
- Key Vault
- Azure Kubernetes Service
- Application Insights
- Azure SignalR Service
- Azure Functions
- Open Terminal - The same terminal you used to install the pre-reqs above.
- Clone Repo
git clone https://github.com/jongio/memealyzer
-
Azure CLI Login
az login
-
Select Azure Subscription - If you have more than one subscription, make sure you have the right one selected.
az account set -s {SUBSCRIPTION_NAME}
-
Set Terraform Variables
- Open
.env
file in the root of this project. Set theBASENAME
setting to something unique
- Open
-
Create Azure Resources with Terraform
-
CD to
iac/terraform
-
Terraform init:
terraform init
-
Terraform plan:
This will create a new Terraform workspace, activate it, and create a new plan file called
tf.plan
.- For local dev:
./plan.sh
- For staging:
./plan.sh staging
- For prod:
./plan.sh prod
You can pass any value as the first parameter. You just need a matching
.env.{workspace}
file in the root of the repo. - For local dev:
-
Terraform apply:
./apply.sh
- This will deploy the above resources to Azure. It will use thetf.plan
that was generated from the previous step.
If you get this error:
Error validating token: IDX10223
, then runaz logout
,az login
, and then run./plan.sh
and./apply.sh
again. -
This app uses the Azure CLI login to connect to Azure resources for local development. You need to run the following script to assign the appropriate roles to the Azure CLI user and the Managed Identity accounts for the Azure Kubernetes Service cluster and the Functions app.
- CD to
iac/terraform
- Run
./perms.sh {basename}
You need to replace
{basename}
with the basename you set in yourBASENAME
setting used above, such asmemealyzerdev
ormemealyzerprod
.
If you are running the .NET versino of this project locally, then you will need to install the following tools.
- .NET Core SDK - 5.0
- Azure Functions Core Tools - v3.0.2881 minimum
- CD to
/pac/net/tye/local
and run./run.sh dev
- Navigate to http://localhost:5000
- CD to the
pac/{lang}/docker
folder for the language you would like to run, i.e. for .NET, cd topac/net/docker
. - Open
.env
and set the following:API_ENDPOINT=http://localhost:2080
FUNCTIONS_ENDPOINT=http://localhost:3080
- Run Docker Compose to start the API, WebApp, Service, and Azurite containers.
- Run:
./run.sh
- Run:
- Start Azure Function
- Run
./func.sh
- Run
- Navigate to http://localhost:1080
- In Docker Desktop settings, Enable Kubernetes and setup to use WSL 2 as backend. Docker Desktop WSL 2 backend
- CD to
pac/net/kubectl/local
. - Run
./run.sh
- Navigate to http://localhost:31389
-
Terraform Workspace
- It is recommended that you create another Azure deployment in a new Terraform workspace, so you can have a dev backend and a prod backend. i.e.
iac/terraform/plan.sh prod
, whereprod
is the name of the workspace and the name of the env file, i.e.env.prod
.
See the "Azure Setup" steps above for full Terraform deployment steps.
The
{basename}
value is pulled from your .env file:TF_VAR_basename
. - It is recommended that you create another Azure deployment in a new Terraform workspace, so you can have a dev backend and a prod backend. i.e.
-
AKS Credentials
- Run the following command to get the AKS cluster credentials locally:
az aks get-credentials --resource-group {basename}rg --name {basename}aks
Replace
{basename}
with the basename you used when you created your Azure resources. -
Kubernetes Context
- Make sure the
K8S_CONTEXT
setting in your .env file is set to the desired value, which will be{basename}aks
.
- Make sure the
-
Nginx Ingress Controller Install
- Install Helm - This will be used for an nginx ingress controller that will expose a Public IP for our cluster and handle routing.
- Set your kubectl context with:
kubectl config use-context {basename}aks
- Run
./scripts/nginx.sh
to install the nginx-ingress controller to your AKS cluster.
-
AKS Cluster IP Address
- Run
az network public-ip list -g memealyzerdevaksnodes --query '[0].ipAddress' --output tsv
to find the AKS cluster's public IP address.
- Run
-
Update .env File
- Open
./.env
and change. (Use./.env.prod
for production environment)
FUNCTIONS_ENDPOINT
to the URI of your functions endpoint, i.e.https://memealyzerdevfunction.azurewebsites.net
- this was outputted by your Terraform run and can be found in your.env
file.
- Open
-
Deploy:
You can choose to either deploy with kubectl or Project Tye.
-
With kubectl
- CD to
/pac/net/kubectl/aks
- CD to
-
With Project Tye
- CD to
/pac/net/tye
- CD to
-
Run
./deploy.sh {env}
, where env is the name of the environment you want to deploy to, this will match your .env file in the project root. -
This will build containers, push them to ACR, apply Kubernetes files, and deploy the Azure Function.
-
- Click on the " " icon to add a random meme.
- Memealyzer will analyize the sentiment of that meme and change the border color to red (negative), yellow (neutral), or green (positive) depending on the sentiment.
You can configure which store the app uses to persist your image metadata, either Cosmos DB or Azure Table Storage.
- Open
.env
file - Find the
AZURE_STORAGE_TYPE
setting - Set it to one of the following values:
COSMOS_SQL
- This will instruct the app to use Cosmos DB.STORAGE_TABLE
- This will instruct the app to use Azure Storage Tables.
You can configure the image border style with the Azure App Configuration service. It will default to solid
, but you can change it to any valid CSS border style. You can either do this in the Azure Portal, or via the Azure CLI with this command:
az appconfig kv set -y -n {basename}appconfig --key borderStyle --value dashed
Replace {basename} with the basename you used when you created your Azure resources above.
After you change the setting, reload the WebApp to see the new style take effect.
You can add override any of the following environment variables to suit your needs. Memealyzer chooses smart defaults that match what is created when you deploy the app with Terraform.
Name | Default Value |
---|---|
BASENAME | This is the only variable that you are required to set. |
AZURE_COSMOS_ENDPOINT | https://${BASENAME}cosmosaccount.documents.azure.com:443 |
AZURE_FORM_RECOGNIZER_ENDPOINT | https://${BASENAME}fr.cognitiveservices.azure.com/ |
AZURE_KEYVAULT_ENDPOINT | https://${BASENAME}kv.vault.azure.net/ |
AZURE_STORAGE_ACCOUNT_NAME | ${BASENAME}storage |
AZURE_STORAGE_BLOB_ENDPOINT | https://${BASENAME}storage.blob.core.windows.net/ |
AZURE_STORAGE_QUEUE_ENDPOINT | https://${BASENAME}storage.queue.core.windows.net/ |
AZURE_STORAGE_TABLE_ENDPOINT | https://${BASENAME}storage.table.core.windows.net/ |
AZURE_TEXT_ANALYTICS_ENDPOINT | https://${BASENAME}ta.cognitiveservices.azure.com/ |
AZURE_APP_CONFIG_ENDPOINT | https://${BASENAME}appconfig.azconfig.io |
AZURE_CONTAINER_REGISTRY_SERVER | ${BASENAME}acr.azurecr.io |
AZURE_STORAGE_BLOB_CONTAINER_NAME | blobs |
AZURE_STORAGE_QUEUE_NAME | messages |
AZURE_STORAGE_QUEUE_MSG_COUNT | 10 |
AZURE_STORAGE_QUEUE_RECEIVE_SLEEP | 1 second |
AZURE_STORAGE_TABLE_NAME | images |
AZURE_COSMOS_DB | memealyzer |
AZURE_COSMOS_COLLECTION | images |
AZURE_COSMOS_KEY_SECRET_NAME | CosmosKey |
AZURE_STORAGE_TYPE | COSMOS_SQL |
AZURE_STORAGE_KEY_SECRET_NAME | StorageKey |
AZURE_STORAGE_CLIENT_SYNC_QUEUE_NAME | sync |
AZURE_SIGNALR_CONNECTION_STRING_SECRET_NAME | SignalRConnectionString |
AZURE_STORAGE_CONNECTION_STRING_SECRET_NAME | StorageConnectionString |
MEME_ENDPOINT | https://meme-api.herokuapp.com/gimme/wholesomememes |
AZURITE_ACCOUNT_KEY | Default value in .env files |
AZURE_COSMOS_KEY | Default value in .env files |