Skip to content

Instantly share code, notes, and snippets.

@avinashupadhya99
Last active May 29, 2022 11:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avinashupadhya99/37ba40a9641efe96343583d40327d4c1 to your computer and use it in GitHub Desktop.
Save avinashupadhya99/37ba40a9641efe96343583d40327d4c1 to your computer and use it in GitHub Desktop.

Architecture

image

Blue services - Commission component

Red services - Manufacturing component

Pre-requisites

  • An Azure account with the CLI configured
  • An Elastic cluster (Easy with elastic Cloud)
  • 3 Postgres database (Heroku can be used)
  • A RabbitMQ cluster (CloudAMQP can be used)
  • jq tool install in your command line (Optional. Necessary for extracting the account key of a storage account. Account key can be manually fetched as well.)

Instructions

Set required environment variables

# Order postgres database connection values
export ORDER_DATABASE_HOST=
export ORDER_DATABASE_NAME=
export ORDER_DATABASE_PORT=
export ORDER_DATABASE_USER=
export ORDER_DATABASE_PASSWORD=

# Billing postgres database connection values
export BILLING_DATABASE_HOST=
export BILLING_DATABASE_NAME=
export BILLING_DATABASE_PORT=
export BILLING_DATABASE_USER=
export BILLING_DATABASE_PASSWORD=

# Manufacturing component postgres database connection values
export MANUFACTURING_DATABASE_HOST=
export MANUFACTURING_DATABASE_NAME=
export MANUFACTURING_DATABASE_PORT=
export MANUFACTURING_DATABASE_USER=
export MANUFACTURING_DATABASE_PASSWORD=

# RabbitMQ connection values
export RABBITMQ_HOST=
export RABBITMQ_PORT=
export RABBITMQ_USER=
export RABBITMQ_PASSWORD=
export RABBITMQ_VHOST=$RABBITMQ_USER
export RABBITMQ_EXCHANGE=commission.exchange
export RABBITMQ_QUEUE=commission.email.queue
export RABBITMQ_ROUTINGKEY=secure.rotating.key

# Elastic APM server
export ELASTIC_APM_SERVER_URL=
export ELASTIC_APM_SECRET_TOKEN=

# Azure
export AZ_LOCATION=centralindia
export AZ_RESOURCE_GROUP=spring-cloud-elastic-apm-lab
export AZ_SPRING_CLOUD_NAME=distributed-elastic-apm-spring
export AZ_STORAGE_ACCOUNT=apmagents
export AZ_SPRING_STORAGE=elastic-apm-agent
export AZ_STORAGE_SHARE=elastic-apm

Create Azure resources

# Create resource group
az group create --location $AZ_LOCATION --name $AZ_RESOURCE_GROUP

# Create Storage Account for storing the APM agents
az storage account create --name $AZ_STORAGE_ACCOUNT \
    --resource-group $AZ_RESOURCE_GROUP \
    --sku Standard_LRS \
    --location $AZ_LOCATION
    
# Get storage account key (Can be manually fetched from portal or by running 
# az storage account keys list -g $AZ_RESOURCE_GROUP -n $AZ_STORAGE_ACCOUNT
# without the jq tool
export AZ_STORAGE_ACCOUNT_KEY=`az storage account keys list -g $AZ_RESOURCE_GROUP -n $AZ_STORAGE_ACCOUNT | jq -r '.[1].value'`

# Create file share
az storage share create --name $AZ_STORAGE_SHARE \
    --account-key $AZ_STORAGE_ACCOUNT_KEY \
    --account-name $AZ_STORAGE_ACCOUNT 

# Download the elastic APM agent locally
curl -L -o elastic-apm-agent-1.31.0.jar 'https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=co.elastic.apm&a=elastic-apm-agent&v=1.31.0'

# Upload elastic APM agent to the file share
az storage file upload --account-name $AZ_STORAGE_ACCOUNT \
    --account-key $AZ_STORAGE_ACCOUNT_KEY \
    --share-name $AZ_STORAGE_SHARE \
    --source elastic-apm-agent-1.31.0.jar

# Install spring extension
az extension add --name spring

# Create spring cloud cluster
az spring create \
    -g $AZ_RESOURCE_GROUP \
    -n $AZ_SPRING_CLOUD_NAME \
    --sku standard
    
# Add storage to spring cloud cluster
az spring storage add \
   --resource-group $AZ_RESOURCE_GROUP \
   --service $AZ_SPRING_CLOUD_NAME \
   --name $AZ_SPRING_STORAGE \
   --storage-type StorageAccount \
   --account-name $AZ_STORAGE_ACCOUNT \
   --account-key $AZ_STORAGE_ACCOUNT_KEY

declare -a services=("order-service" "billing-service" "email-service" "produce-service" "package-service")

for service in "${services[@]}"
do
    # Create spring boot apps
    az spring app create -n $service \
        --assign-endpoint true \
        --runtime-version Java_11 \
        -g $AZ_RESOURCE_GROUP \
        -s $AZ_SPRING_CLOUD_NAME

    # Attach storage to app
    az spring-cloud app append-persistent-storage \
       --resource-group $AZ_RESOURCE_GROUP \
       --service $AZ_SPRING_CLOUD_NAME \
       --name $service \
       --persistent-storage-type AzureFileVolume \
       --share-name $AZ_STORAGE_SHARE \
       --mount-path /opt/agents/elastic/agent \
       --storage-name $AZ_SPRING_STORAGE
done

Deploying services

Produce Service

git clone https://github.com/avinashupadhya99/produce-service
cd produce-service
export DATABASE_HOST=$MANUFACTURING_DATABASE_HOST
export DATABASE_NAME=$MANUFACTURING_DATABASE_NAME
export DATABASE_PORT=$MANUFACTURING_DATABASE_PORT
export DATABASE_USER=$MANUFACTURING_DATABASE_USER
export DATABASE_PASSWORD=$MANUFACTURING_DATABASE_PASSWORD
./mvnw clean package
az spring app deploy \
    --name produce-service \
    --resource-group $AZ_RESOURCE_GROUP \
    --service $AZ_SPRING_CLOUD_NAME \
    --artifact-path target/produce-0.0.1-SNAPSHOT.jar \
    --jvm-options=-javaagent:"/opt/agents/elastic/agent/elastic-apm-agent-1.31.0.jar" \
    --env ELASTIC_APM_SERVICE_NAME=produce-service \
          ELASTIC_APM_APPLICATION_PACKAGES=com.production \
          ELASTIC_APM_SERVER_URL=$ELASTIC_APM_SERVER_URL \
          ELASTIC_APM_SECRET_TOKEN=$ELASTIC_APM_SECRET_TOKEN \
          DATABASE_HOST=$DATABASE_HOST \
          DATABASE_NAME=$DATABASE_NAME \
          DATABASE_PORT=$DATABASE_PORT \
          DATABASE_USER=$DATABASE_USER \
          DATABASE_PASSWORD=$DATABASE_PASSWORD

Billing Service

git clone https://github.com/avinashupadhya99/billing-service
cd billing-service
export DATABASE_HOST=$BILLING_DATABASE_HOST
export DATABASE_NAME=$BILLING_DATABASE_NAME
export DATABASE_PORT=$BILLING_DATABASE_PORT
export DATABASE_USER=$BILLING_DATABASE_USER
export DATABASE_PASSWORD=$BILLING_DATABASE_PASSWORD
./mvnw clean package
az spring app deploy \
    --name billing-service \
    --resource-group $AZ_RESOURCE_GROUP \
    --service $AZ_SPRING_CLOUD_NAME \
    --artifact-path target/billing-0.0.1-SNAPSHOT.jar \
    --jvm-options=-javaagent:"/opt/agents/elastic/agent/elastic-apm-agent-1.31.0.jar" \
    --env ELASTIC_APM_SERVICE_NAME=billing-service \
          ELASTIC_APM_APPLICATION_PACKAGES=com.commission \
          ELASTIC_APM_SERVER_URL=$ELASTIC_APM_SERVER_URL \
          ELASTIC_APM_SECRET_TOKEN=$ELASTIC_APM_SECRET_TOKEN \
          DATABASE_HOST=$DATABASE_HOST \
          DATABASE_NAME=$DATABASE_NAME \
          DATABASE_PORT=$DATABASE_PORT \
          DATABASE_USER=$DATABASE_USER \
          DATABASE_PASSWORD=$DATABASE_PASSWORD \
          RABBITMQ_HOST=$RABBITMQ_HOST \
          RABBITMQ_PORT=$RABBITMQ_PORT \
          RABBITMQ_USER=$RABBITMQ_USER \
          RABBITMQ_PASSWORD=$RABBITMQ_PASSWORD \
          RABBITMQ_VHOST=$RABBITMQ_VHOST \
          RABBITMQ_EXCHANGE=$RABBITMQ_EXCHANGE \
          RABBITMQ_QUEUE=$RABBITMQ_QUEUE \
          RABBITMQ_ROUTINGKEY=$RABBITMQ_ROUTINGKEY

Email Service

git clone https://github.com/avinashupadhya99/email-service
cd email-service
./mvnw clean package
az spring app deploy \
    --name email-service \
    --resource-group $AZ_RESOURCE_GROUP \
    --service $AZ_SPRING_CLOUD_NAME \
    --artifact-path target/email-0.0.1-SNAPSHOT.jar \
    --jvm-options=-javaagent:"/opt/agents/elastic/agent/elastic-apm-agent-1.31.0.jar" \
    --env ELASTIC_APM_SERVICE_NAME=email-service \
          ELASTIC_APM_APPLICATION_PACKAGES=com.commission \
          ELASTIC_APM_SERVER_URL=$ELASTIC_APM_SERVER_URL \
          ELASTIC_APM_SECRET_TOKEN=$ELASTIC_APM_SECRET_TOKEN \
          RABBITMQ_HOST=$RABBITMQ_HOST \
          RABBITMQ_PORT=$RABBITMQ_PORT \
          RABBITMQ_USER=$RABBITMQ_USER \
          RABBITMQ_PASSWORD=$RABBITMQ_PASSWORD \
          RABBITMQ_VHOST=$RABBITMQ_VHOST \
          RABBITMQ_QUEUE=$RABBITMQ_QUEUE 

Order Service

git clone https://github.com/avinashupadhya99/order-service
cd order-service
export DATABASE_HOST=$ORDER_DATABASE_HOST
export DATABASE_NAME=$ORDER_DATABASE_NAME
export DATABASE_PORT=$ORDER_DATABASE_PORT
export DATABASE_USER=$ORDER_DATABASE_USER
export DATABASE_PASSWORD=$ORDER_DATABASE_PASSWORD
# Store the billing and produce service URL using jq or manually
export BILLING_SERVICE_URL=`az spring app show --name billing-service --resource-group $AZ_RESOURCE_GROUP --service $AZ_SPRING_CLOUD_NAME | jq -r '.properties.url'`
export PRODUCE_SERVICE_URL=`az spring app show --name produce-service --resource-group $AZ_RESOURCE_GROUP --service $AZ_SPRING_CLOUD_NAME | jq -r '.properties.url'`
./mvnw clean package
az spring app deploy \
    --name order-service \
    --resource-group $AZ_RESOURCE_GROUP \
    --service $AZ_SPRING_CLOUD_NAME \
    --artifact-path target/order-0.0.1-SNAPSHOT.jar \
    --jvm-options=-javaagent:"/opt/agents/elastic/agent/elastic-apm-agent-1.31.0.jar" \
    --env ELASTIC_APM_SERVICE_NAME=order-service \
          ELASTIC_APM_APPLICATION_PACKAGES=com.commission \
          ELASTIC_APM_SERVER_URL=$ELASTIC_APM_SERVER_URL \
          ELASTIC_APM_SECRET_TOKEN=$ELASTIC_APM_SECRET_TOKEN \
          DATABASE_HOST=$DATABASE_HOST \
          DATABASE_NAME=$DATABASE_NAME \
          DATABASE_PORT=$DATABASE_PORT \
          DATABASE_USER=$DATABASE_USER \
          DATABASE_PASSWORD=$DATABASE_PASSWORD \
          PRODUCE_SERVICE_URL=$PRODUCE_SERVICE_URL \
          BILLING_SERVICE_URL=$BILLING_SERVICE_URL

Package Service

git clone https://github.com/avinashupadhya99/package-service
cd package-service
export DATABASE_HOST=$MANUFACTURING_DATABASE_HOST
export DATABASE_NAME=$MANUFACTURING_DATABASE_NAME
export DATABASE_PORT=$MANUFACTURING_DATABASE_PORT
export DATABASE_USER=$MANUFACTURING_DATABASE_USER
export DATABASE_PASSWORD=$MANUFACTURING_DATABASE_PASSWORD
# Store the order service URL using jq or manually
export ORDER_SERVICE_URL=`az spring app show --name order-service --resource-group $AZ_RESOURCE_GROUP --service $AZ_SPRING_CLOUD_NAME | jq -r '.properties.url'`
./mvnw clean package
az spring app deploy \
    --name package-service \
    --resource-group $AZ_RESOURCE_GROUP \
    --service $AZ_SPRING_CLOUD_NAME \
    --artifact-path target/package-0.0.1-SNAPSHOT.jar \
    --jvm-options=-javaagent:"/opt/agents/elastic/agent/elastic-apm-agent-1.31.0.jar" \
    --env ELASTIC_APM_SERVICE_NAME=package-service \
          ELASTIC_APM_APPLICATION_PACKAGES=com.production \
          ELASTIC_APM_SERVER_URL=$ELASTIC_APM_SERVER_URL \
          ELASTIC_APM_SECRET_TOKEN=$ELASTIC_APM_SECRET_TOKEN \
          DATABASE_HOST=$DATABASE_HOST \
          DATABASE_NAME=$DATABASE_NAME \
          DATABASE_PORT=$DATABASE_PORT \
          DATABASE_USER=$DATABASE_USER \
          DATABASE_PASSWORD=$DATABASE_PASSWORD \
          ORDER_SERVICE_URL=$ORDER_SERVICE_URL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment