|
--- |
|
- name: Deploy Spring Boot Applications and Configure Azure Resources |
|
hosts: localhost |
|
vars: |
|
resource_group: resourcegroup1 |
|
location: eastus |
|
app_plan_name: app-plan |
|
gw_plan_name: gw-plan |
|
app_instances: |
|
- testapp1 |
|
- testapp2 |
|
gw_instances: |
|
- gateway |
|
jar_directory: "/path/to/jars" |
|
num_app_instances: 4 # Global variable for the number of instances per app |
|
num_gw_instances: 1 # Number of gateway instances |
|
app_prefix: "app" |
|
gw_prefix: "gw" |
|
address_prefixes: "10.0.0.0/16" |
|
subnet_prefix: "10.0.1.0/24" |
|
app_gateway_subnet_prefix: "10.0.2.0/24" |
|
app_gateway_name: appGateway |
|
vnet_name: appVNet |
|
subnet_name: appSubnet |
|
app_gateway_subnet_name: appGatewaySubnet |
|
app_env: "{{ app_env_param }}" # Parameter for app.env, default value if not passed |
|
|
|
tasks: |
|
- name: Create resource group |
|
command: > |
|
az group create --name {{ resource_group }} --location {{ location }} |
|
ignore_errors: yes |
|
|
|
- name: Determine spring_boot_apps for app_instances |
|
set_fact: |
|
spring_boot_apps: "{{ spring_boot_apps | default([]) + [{'name': item, 'jar_path': jar_directory + '/' + item + '.jar', 'plan': app_plan_name}] }}" |
|
with_items: "{{ app_instances }}" |
|
|
|
- name: Determine spring_boot_apps for gw_instances |
|
set_fact: |
|
spring_boot_apps: "{{ spring_boot_apps + [{'name': item, 'jar_path': jar_directory + '/' + item + '.jar', 'plan': gw_plan_name}] }}" |
|
with_items: "{{ gw_instances }}" |
|
|
|
- name: Create service plans |
|
command: > |
|
az appservice plan create --name {{ item.plan }} --resource-group {{ resource_group }} --location {{ location }} --sku F1 --is-linux |
|
loop: |
|
- "{{ app_plan_name }}" |
|
- "{{ gw_plan_name }}" |
|
|
|
- name: Create web apps |
|
command: > |
|
az webapp create --name {{ item.name }} --resource-group {{ resource_group }} --plan {{ item.plan }} --runtime "JAVA|11-java11" |
|
with_items: "{{ spring_boot_apps }}" |
|
|
|
- name: Deploy JAR files to Azure Web Apps |
|
command: > |
|
az webapp deploy --resource-group {{ resource_group }} --name {{ item.name }} --src-path {{ item.jar_path }} --type jar > /dev/null 2>&1 |
|
with_items: "{{ spring_boot_apps }}" |
|
|
|
- name: Set spring.profiles.active and app.env properties |
|
command: > |
|
az webapp config appsettings set --resource-group {{ resource_group }} --name {{ item.name }} --settings spring.profiles.active=azure app.env={{ app_env }} |
|
with_items: "{{ spring_boot_apps }}" |
|
|
|
- name: Get App Plan ID |
|
command: az appservice plan show --name {{ app_plan_name }} --resource-group {{ resource_group }} --query id --output tsv |
|
register: app_plan_id |
|
changed_when: false |
|
|
|
- name: Get GW Plan ID |
|
command: az appservice plan show --name {{ gw_plan_name }} --resource-group {{ resource_group }} --query id --output tsv |
|
register: gw_plan_id |
|
changed_when: false |
|
|
|
- name: Create Virtual Network |
|
command: > |
|
az network vnet create --name {{ vnet_name }} |
|
--resource-group {{ resource_group }} |
|
--address-prefixes {{ address_prefixes }} |
|
--subnet-name {{ subnet_name }} |
|
--subnet-prefix {{ subnet_prefix }} |
|
register: vnet |
|
changed_when: false |
|
|
|
- name: Create App Gateway Subnet |
|
command: > |
|
az network vnet subnet create --vnet-name {{ vnet_name }} |
|
--name {{ app_gateway_subnet_name }} |
|
--resource-group {{ resource_group }} |
|
--address-prefix {{ app_gateway_subnet_prefix }} |
|
register: app_gateway_subnet |
|
changed_when: false |
|
|
|
- name: Create and Move App Instances |
|
command: > |
|
az webapp create --name {{ item.app_name }}-{{ item.instance }} |
|
--resource-group {{ resource_group }} |
|
--plan {{ app_plan_id.stdout }} |
|
--runtime "JAVA|11-java11" |
|
with_subelements: |
|
- "{{ app_instances | map('product', with_sequence('start=1 end=' + num_app_instances|string)) | list }}" |
|
- list |
|
|
|
- name: Create and Move GW Instances |
|
command: > |
|
az webapp create --name {{ gw_prefix }}-{{ item }} |
|
--resource-group {{ resource_group }} |
|
--plan {{ gw_plan_id.stdout }} |
|
--runtime "JAVA|11-java11" |
|
with_sequence: start=1 end={{ num_gw_instances }} |
|
|
|
- name: Integrate App Instances with VNet |
|
command: > |
|
az webapp vnet-integration add --name {{ item.app_name }}-{{ item.instance }} |
|
--resource-group {{ resource_group }} |
|
--vnet {{ vnet_name }} |
|
--subnet {{ subnet_name }} |
|
with_subelements: |
|
- "{{ app_instances | map('product', with_sequence('start=1 end=' + num_app_instances|string)) | list }}" |
|
- list |
|
|
|
- name: Integrate GW Instances with VNet |
|
command: > |
|
az webapp vnet-integration add --name {{ gw_prefix }}-{{ item }} |
|
--resource-group {{ resource_group }} |
|
--vnet {{ vnet_name }} |
|
--subnet {{ subnet_name }} |
|
with_sequence: start=1 end={{ num_gw_instances }} |
|
|
|
- name: Create Private Endpoints for App Instances |
|
command: > |
|
az network private-endpoint create --name {{ item.app_name }}-{{ item.instance }}PrivateEndpoint |
|
--resource-group {{ resource_group }} |
|
--vnet-name {{ vnet_name }} |
|
--subnet {{ subnet_name }} |
|
--private-connection-resource-id $(az webapp show --name {{ item.app_name }}-{{ item.instance }} --resource-group {{ resource_group }} --query id --output tsv) |
|
--group-ids sites |
|
--connection-name {{ item.app_name }}-{{ item.instance }}Connection |
|
with_subelements: |
|
- "{{ app_instances | map('product', with_sequence('start=1 end=' + num_app_instances|string)) | list }}" |
|
- list |
|
|
|
- name: Determine Private IP Addresses |
|
command: > |
|
az network private-endpoint show --name {{ item.app_name }}-{{ item.instance }}PrivateEndpoint |
|
--resource-group {{ resource_group }} |
|
--query 'customDnsConfigurations[0].ipAddresses[0]' |
|
--output tsv |
|
register: private_ips |
|
with_subelements: |
|
- "{{ app_instances | map('product', with_sequence('start=1 end=' + num_app_instances|string)) | list }}" |
|
- list |
|
changed_when: false |
|
|
|
- name: Configure Private DNS Zones |
|
command: az network private-dns zone create --resource-group {{ resource_group }} --name privatelink.azurewebsites.net |
|
|
|
- name: Link VNet to Private DNS Zone |
|
command: > |
|
az network private-dns link vnet create --resource-group {{ resource_group }} |
|
--zone-name privatelink.azurewebsites.net |
|
--name appVNetLink |
|
--virtual-network {{ vnet_name }} |
|
--registration-enabled false |
|
|
|
- name: Add DNS Records for App Instances |
|
command: > |
|
az network private-dns record-set a add-record --resource-group {{ resource_group }} |
|
--zone-name privatelink.azurewebsites.net |
|
--record-set-name {{ item.0.app_name }}-{{ item.1.instance }} |
|
--ipv4-address {{ item.1.stdout }} |
|
with_subelements: |
|
- "{{ private_ips.results }}" |
|
- stdout_lines |
|
|
|
- name: Restrict Public Access to App Instances |
|
command: > |
|
az webapp config access-restriction add --name {{ item.app_name }}-{{ item.instance }} |
|
--resource-group {{ resource_group }} |
|
--rule-name DenyPublicAccess |
|
--priority 100 |
|
--action Deny |
|
--ip-address 0.0.0.0/0 |
|
with_subelements: |
|
- "{{ app_instances | map('product', with_sequence('start=1 end=' + num_app_instances|string)) | list }}" |
|
- list |
|
|
|
- name: List all webapps in resource group |
|
command: az webapp list --resource-group {{ resource_group }} --query [].name --output tsv |
|
register: all_webapps |
|
changed_when: false |
|
|
|
- name: Remove Web Apps not in app_instances |
|
command: az webapp delete --resource-group {{ resource_group }} --name {{ item }} |
|
when: "'{{ item }}' not in (app_instances + gw_instances)" |
|
loop: "{{ all_webapps.stdout_lines }}" |
|
|
|
- name: List all private endpoints in resource group |
|
command: az network private-endpoint list --resource-group {{ resource_group }} --query [].name --output tsv |
|
register: all_private_endpoints |
|
changed_when: false |
|
|
|
- name: Remove Private Endpoints not in app_instances |
|
command: az network private-endpoint delete --resource-group {{ resource_group }} --name {{ item }} |
|
when: "'{{ item }}PrivateEndpoint' not in (app_instances | map('join', 'PrivateEndpoint'))" |
|
loop: "{{ all_private_endpoints.stdout_lines }}" |
|
|
|
- name: List all DNS records in private DNS zone |
|
command: az network private-dns record-set list --resource-group {{ resource_group }} --zone-name privatelink.azurewebsites.net --query [].name --output tsv |
|
register: all_dns_records |
|
changed_when: false |
|
|
|
- name: Remove DNS Records not in app_instances |
|
command: > |
|
az network private-dns record-set a remove-record --resource-group {{ resource_group }} |
|
--zone-name privatelink.azurewebsites.net |
|
--record-set-name {{ item }} |
|
--ipv4-address $(az network private-endpoint show --name {{ item }}PrivateEndpoint --resource-group {{ resource_group }} --query 'customDnsConfigurations[0].ipAddresses[0]' --output tsv) |
|
when: "'{{ item }}.privatelink.azurewebsites.net' not in (app_instances | map('join', '.privatelink.azurewebsites.net'))" |
|
loop: "{{ all_dns_records.stdout_lines }}" |